diff --git a/EngineErrorMap.md b/EngineErrorMap.md index cc43012bd5e..1f5573d4ef8 100644 --- a/EngineErrorMap.md +++ b/EngineErrorMap.md @@ -1840,6 +1840,10 @@ Instancing/Batching enabled for non-baked skinning model '%s', this may result i ### 3937 Previous error occurred when instantiating animation clip %s on node %s. +### 3938 + +'%s' is not found from '%s'. It's specified as the root node to play animation clip '%s'. + ### 4000 @@ -3267,4 +3271,4 @@ The shadow visible distance is so small that CSM stratification is not effective ### 15004 -The native folder may be generated from older versions, please refer https://docs.cocos.com/creator/manual/en/release-notes/ to upgrade. \ No newline at end of file +The native folder may be generated from older versions, please refer https://docs.cocos.com/creator/manual/en/release-notes/ to upgrade. diff --git a/cocos/3d/assets/skeleton.jsb.ts b/cocos/3d/assets/skeleton.jsb.ts index 736c3a29414..6a165f93401 100644 --- a/cocos/3d/assets/skeleton.jsb.ts +++ b/cocos/3d/assets/skeleton.jsb.ts @@ -23,11 +23,6 @@ THE SOFTWARE. */ -/** - * @packageDocumentation - * @module asset - */ - import { ccclass, type, serializable } from 'cc.decorator'; import { CCString } from '../../core/data/utils/attribute'; import { Mat4 } from '../../core/math'; diff --git a/cocos/3d/models/skinning-model.ts b/cocos/3d/models/skinning-model.ts index 267d8d12ba9..4ff2e3e07a9 100644 --- a/cocos/3d/models/skinning-model.ts +++ b/cocos/3d/models/skinning-model.ts @@ -28,9 +28,9 @@ import { RenderingSubMesh } from '../../core/assets/rendering-sub-mesh'; import { Mesh } from '../assets/mesh'; import { Skeleton } from '../assets/skeleton'; import { AABB } from '../../core/geometry'; -import { BufferUsageBit, MemoryUsageBit, DescriptorSet, Buffer, BufferInfo, Attribute } from '../../core/gfx'; +import { BufferUsageBit, MemoryUsageBit, DescriptorSet, Buffer, BufferInfo, Attribute, FormatFeatureBit, Format, Texture } from '../../core/gfx'; import { Mat4, Vec3 } from '../../core/math'; -import { UBOSkinning } from '../../core/pipeline/define'; +import { UBOSkinning, UNIFORM_REALTIME_JOINT_TEXTURE_BINDING } from '../../core/pipeline/define'; import { Node } from '../../core/scene-graph/node'; import { ModelType } from '../../core/renderer/scene/model'; import { uploadJointData } from '../skeletal-animation/skeletal-animation-utils'; @@ -38,9 +38,16 @@ import { MorphModel } from './morph-model'; import { deleteTransform, getTransform, getWorldMatrix, IJointTransform } from '../../core/animation/skeletal-animation-utils'; import { IMacroPatch, BatchingSchemes, Pass } from '../../core/renderer'; import { warnID } from '../../core/platform/debug'; +import { ImageAsset, Texture2D, director } from '../../core'; +import { PixelFormat } from '../../core/assets/asset-enum'; -const myPatches: IMacroPatch[] = [ +const uniformPatches: IMacroPatch[] = [ { name: 'CC_USE_SKINNING', value: true }, + { name: 'CC_USE_REAL_TIME_JOINT_TEXTURE', value: false }, +]; +const texturePatches: IMacroPatch[] = [ + { name: 'CC_USE_SKINNING', value: true }, + { name: 'CC_USE_REAL_TIME_JOINT_TEXTURE', value: true }, ]; function getRelevantBuffers (outIndices: number[], outBuffers: number[], jointMaps: number[][], targetJoint: number) { @@ -73,6 +80,14 @@ const v3_2 = new Vec3(); const m4_1 = new Mat4(); const ab_1 = new AABB(); +class RealTimeJointTexture { + public static readonly WIDTH = 256; + public static readonly HEIGHT = 3; + public _format = PixelFormat.RGBA32F; // default use float texture + public _textures: Texture2D[] = []; + public _buffers: Float32Array[] = []; +} + /** * @en * The skinning model that is using real-time pose calculation. @@ -84,6 +99,8 @@ export class SkinningModel extends MorphModel { private _dataArray: Float32Array[] = []; private _joints: IJointInfo[] = []; private _bufferIndices: number[] | null = null; + private _realTimeJointTexture = new RealTimeJointTexture(); + private _realTimeTextureMode = false; constructor () { super(); this.type = ModelType.SKINNING; @@ -97,6 +114,12 @@ export class SkinningModel extends MorphModel { } this._buffers.length = 0; } + this._dataArray.length = 0; + this._realTimeJointTexture._textures.forEach((tex) => { + tex.destroy(); + }); + this._realTimeJointTexture._textures.length = 0; + this._realTimeJointTexture._buffers.length = 0; super.destroy(); } @@ -120,11 +143,14 @@ export class SkinningModel extends MorphModel { } this._bufferIndices = null; this._joints.length = 0; if (!skeleton || !skinningRoot || !mesh) { return; } + this._realTimeTextureMode = false; + if (UBOSkinning.JOINT_UNIFORM_CAPACITY < skeleton.joints.length) { this._realTimeTextureMode = true; } this.transform = skinningRoot; const boneSpaceBounds = mesh.getBoneSpaceBounds(skeleton); const jointMaps = mesh.struct.jointMaps; this._ensureEnoughBuffers(jointMaps && jointMaps.length || 1); this._bufferIndices = mesh.jointBufferIndices; + this._initRealTimeJointTexture(); for (let index = 0; index < skeleton.joints.length; index++) { const bound = boneSpaceBounds[index]; const target = skinningRoot.getChildByPath(skeleton.joints[index]); @@ -185,8 +211,12 @@ export class SkinningModel extends MorphModel { uploadJointData(this._dataArray[buffers[b]], indices[b] * 12, m4_1, i === 0); } } - for (let b = 0; b < this._buffers.length; b++) { - this._buffers[b].update(this._dataArray[b]); + if (this._realTimeTextureMode) { + this._updateRealTimeJointTextureBuffer(); + } else { + for (let b = 0; b < this._buffers.length; b++) { + this._buffers[b].update(this._dataArray[b]); + } } return true; } @@ -209,7 +239,10 @@ export class SkinningModel extends MorphModel { // override public getMacroPatches (subModelIndex: number): IMacroPatch[] | null { const superMacroPatches = super.getMacroPatches(subModelIndex); - + let myPatches = uniformPatches; + if (this._realTimeTextureMode) { + myPatches = texturePatches; + } if (superMacroPatches) { return myPatches.concat(superMacroPatches); } @@ -221,8 +254,13 @@ export class SkinningModel extends MorphModel { */ public _updateLocalDescriptors (submodelIdx: number, descriptorSet: DescriptorSet) { super._updateLocalDescriptors(submodelIdx, descriptorSet); - const buffer = this._buffers[this._bufferIndices![submodelIdx]]; - if (buffer) { descriptorSet.bindBuffer(UBOSkinning.BINDING, buffer); } + const idx = this._bufferIndices![submodelIdx]; + if (this._realTimeTextureMode) { + this._bindRealTimeJointTexture(idx, descriptorSet); + } else { + const buffer = this._buffers[idx]; + if (buffer) { descriptorSet.bindBuffer(UBOSkinning.BINDING, buffer); } + } } protected _updateInstancedAttributes (attributes: Attribute[], pass: Pass) { @@ -234,18 +272,117 @@ export class SkinningModel extends MorphModel { } private _ensureEnoughBuffers (count: number) { - for (let i = 0; i < count; i++) { - if (!this._buffers[i]) { + if (this._buffers.length) { + for (let i = 0; i < this._buffers.length; i++) { + this._buffers[i].destroy(); + } + this._buffers.length = 0; + } + + if (this._dataArray.length) this._dataArray.length = 0; + + if (!this._realTimeTextureMode) { + for (let i = 0; i < count; i++) { this._buffers[i] = this._device.createBuffer(new BufferInfo( BufferUsageBit.UNIFORM | BufferUsageBit.TRANSFER_DST, MemoryUsageBit.HOST | MemoryUsageBit.DEVICE, UBOSkinning.SIZE, UBOSkinning.SIZE, )); + const maxJoints = UBOSkinning.JOINT_UNIFORM_CAPACITY; + this._dataArray[i] = new Float32Array(12 * maxJoints); + } + } else { + for (let i = 0; i < count; i++) { + const maxJoints = RealTimeJointTexture.WIDTH; + this._dataArray[i] = new Float32Array(12 * maxJoints); } - if (!this._dataArray[i]) { - this._dataArray[i] = new Float32Array(UBOSkinning.COUNT); + } + } + + private _initRealTimeJointTexture () { + if (this._realTimeJointTexture._textures.length) { + this._realTimeJointTexture._textures.forEach((tex) => { + tex.destroy(); + }); + this._realTimeJointTexture._textures.length = 0; + } + this._realTimeJointTexture._buffers.length = 0; + if (!this._realTimeTextureMode) return; + + const gfxDevice = director.root!.device; + let width = RealTimeJointTexture.WIDTH; + const height = RealTimeJointTexture.HEIGHT; + const hasFeatureFloatTexture = gfxDevice.getFormatFeatures(Format.RGBA32F) & FormatFeatureBit.SAMPLED_TEXTURE; + if (hasFeatureFloatTexture === 0) { + this._realTimeJointTexture._format = PixelFormat.RGBA8888; + width = 4 * RealTimeJointTexture.WIDTH; + } + + const textures = this._realTimeJointTexture._textures; + const buffers = this._realTimeJointTexture._buffers; + const pixelFormat = this._realTimeJointTexture._format; + for (let i = 0; i < this._dataArray.length; i++) { + buffers[i] = new Float32Array(4 * RealTimeJointTexture.HEIGHT * RealTimeJointTexture.WIDTH); + const arrayBuffer = buffers[i]; + const updateView = pixelFormat === PixelFormat.RGBA32F ? arrayBuffer : new Uint8Array(arrayBuffer.buffer); + const image = new ImageAsset({ + width, + height, + _data: updateView, + _compressed: false, + format: pixelFormat, + }); + const texture = new Texture2D(); + texture.setFilters(Texture2D.Filter.NEAREST, Texture2D.Filter.NEAREST); + texture.setMipFilter(Texture2D.Filter.NONE); + texture.setWrapMode(Texture2D.WrapMode.CLAMP_TO_EDGE, Texture2D.WrapMode.CLAMP_TO_EDGE, Texture2D.WrapMode.CLAMP_TO_EDGE); + texture.image = image; + textures[i] = texture; + } + } + + private _bindRealTimeJointTexture (idx: number, descriptorSet: DescriptorSet) { + if (!this._realTimeTextureMode) return; + const jointTexture = this._realTimeJointTexture._textures[idx]; + if (jointTexture) { + const gfxTexture = jointTexture.getGFXTexture(); + const sampler = jointTexture.getGFXSampler(); + descriptorSet.bindTexture(UNIFORM_REALTIME_JOINT_TEXTURE_BINDING, gfxTexture!); + descriptorSet.bindSampler(UNIFORM_REALTIME_JOINT_TEXTURE_BINDING, sampler); + } + } + + private _updateRealTimeJointTextureBuffer () { + if (!this._realTimeTextureMode) return; + const textures = this._realTimeJointTexture._textures; + const buffers = this._realTimeJointTexture._buffers; + for (let idx = 0; idx < textures.length; idx++) { + const arrayBuffer = buffers[idx]; + const src = this._dataArray[idx]; + const count = src.length / 12; // mat3x4 + let idxSrc = 0; + let idxDst = 0; + for (let i = 0; i < count; i++) { + idxDst = 4 * i; + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; + idxDst = 4 * (i + RealTimeJointTexture.WIDTH); + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; + idxDst = 4 * (i + 2 * RealTimeJointTexture.WIDTH); + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; + arrayBuffer[idxDst++] = src[idxSrc++]; } + const pixelFormat = this._realTimeJointTexture._format; + const updateView = pixelFormat === PixelFormat.RGBA32F ? arrayBuffer : new Uint8Array(arrayBuffer.buffer); + textures[idx].uploadData(updateView); } } } diff --git a/cocos/core/animation/animation-clip.ts b/cocos/core/animation/animation-clip.ts index 5ad0830be4b..bc7ba9287a6 100644 --- a/cocos/core/animation/animation-clip.ts +++ b/cocos/core/animation/animation-clip.ts @@ -34,7 +34,7 @@ import { murmurhash2_32_gc } from '../utils/murmurhash2_gc'; import { SkelAnimDataHub } from '../../3d/skeletal-animation/skeletal-animation-data-hub'; import { WrapMode as AnimationWrapMode, WrapMode, WrapModeMask } from './types'; import { legacyCC } from '../global-exports'; -import { Mat4, Quat, Vec3 } from '../math'; +import { approx, clamp, Mat4, Quat, Vec3 } from '../math'; import { Node } from '../scene-graph/node'; import { assertIsTrue } from '../data/utils/asserts'; import type { PoseOutput } from './pose-output'; @@ -50,6 +50,7 @@ import './exotic-animation/exotic-animation'; import { array } from '../utils/js'; import type { AnimationMask } from './marionette/animation-mask'; import { getGlobalAnimationManager } from './global-animation-manager'; +import { EmbeddedPlayableState, EmbeddedPlayer } from './embedded-player/embedded-player'; export declare namespace AnimationClip { export interface IEvent { @@ -83,6 +84,12 @@ interface SkeletonAnimationBakeInfo { export const exoticAnimationTag = Symbol('ExoticAnimation'); +export const embeddedPlayerCountTag = Symbol('[[EmbeddedPlayerCount]]'); +export const getEmbeddedPlayersTag = Symbol('[[GetEmbeddedPlayers]]'); +export const addEmbeddedPlayerTag = Symbol('[[AddEmbeddedPlayer]]'); +export const removeEmbeddedPlayerTag = Symbol('[[RemoveEmbeddedPlayer]]'); +export const clearEmbeddedPlayersTag = Symbol('[[ClearEmbeddedPlayers]]'); + /** * @zh 动画剪辑表示一段使用动画编辑器编辑的关键帧动画或是外部美术工具生产的骨骼动画。 * 它的数据主要被分为几层:轨道、关键帧和曲线。 @@ -580,6 +587,44 @@ export class AnimationClip extends Asset { // #endregion + /** + * @internal + */ + get [embeddedPlayerCountTag] () { + return this._embeddedPlayers.length; + } + + /** + * @internal + */ + public [getEmbeddedPlayersTag] (): Iterable { + return this._embeddedPlayers; + } + + /** + * @internal + */ + public [addEmbeddedPlayerTag] (embeddedPlayer: EmbeddedPlayer) { + this._embeddedPlayers.push(embeddedPlayer); + } + + /** + * @internal + */ + public [removeEmbeddedPlayerTag] (embeddedPlayer: EmbeddedPlayer) { + const iEmbeddedPlayer = this._embeddedPlayers.indexOf(embeddedPlayer); + if (iEmbeddedPlayer >= 0) { + this._embeddedPlayers.splice(iEmbeddedPlayer, 1); + } + } + + /** + * @internal + */ + public [clearEmbeddedPlayersTag] () { + this._embeddedPlayers.length = 0; + } + @serializable private _duration = 0; @@ -601,6 +646,9 @@ export class AnimationClip extends Asset { @serializable private _events: AnimationClip.IEvent[] = []; + @serializable + private _embeddedPlayers: EmbeddedPlayer[] = []; + private _runtimeEvents: { ratios: number[]; eventGroups: IAnimationEventGroup[]; @@ -653,10 +701,19 @@ export class AnimationClip extends Asset { exoticAnimationEvaluator = this._exoticAnimation.createEvaluator(binder); } + let embeddedPlayerEvaluation: EmbeddedPlayerEvaluation | undefined; + if (target instanceof Node) { // Note: when this method is called from bake(), target is undefined. + const { _embeddedPlayers: embeddedPlayers } = this; + if (this._embeddedPlayers.length !== 0) { + embeddedPlayerEvaluation = new EmbeddedPlayerEvaluation(embeddedPlayers, target); + } + } + const evaluation = new AnimationClipEvaluation( trackEvalStatues, exoticAnimationEvaluator, rootMotionEvaluation, + embeddedPlayerEvaluation, ); return evaluation; @@ -857,15 +914,167 @@ interface RootMotionOptions { type ExoticAnimationEvaluator = ReturnType; +class EmbeddedPlayerEvaluation { + constructor (embeddedPlayers: ReadonlyArray, rootNode: Node) { + this._embeddedPlayers = embeddedPlayers; + this._embeddedPlayerEvaluationInfos = embeddedPlayers.map( + (embeddedPlayer): EmbeddedPlayerEvaluation['_embeddedPlayerEvaluationInfos'][0] => { + const { playable: player } = embeddedPlayer; + if (!player) { + return null; + } + const instantiatedPlayer = player.instantiate(rootNode); + if (!instantiatedPlayer) { + return null; + } + return { + instantiatedPlayer, + entered: false, + hostPauseTime: 0.0, + }; + }, + ); + } + + public evaluate (time: number) { + const { + _embeddedPlayers: embeddedPlayers, + _embeddedPlayerEvaluationInfos: embeddedPlayerEvaluationInfos, + } = this; + const nEmbeddedPlayers = embeddedPlayers.length; + for (let iEmbeddedPlayer = 0; iEmbeddedPlayer < nEmbeddedPlayers; ++iEmbeddedPlayer) { + const embeddedPlayerEvaluationInfo = embeddedPlayerEvaluationInfos[iEmbeddedPlayer]; + if (!embeddedPlayerEvaluationInfo) { + continue; + } + const { entered, instantiatedPlayer } = embeddedPlayerEvaluationInfo; + const { begin, end } = embeddedPlayers[iEmbeddedPlayer]; + const withinEmbeddedPlayer = time >= begin && time <= end; + if (withinEmbeddedPlayer) { + if (!entered) { + instantiatedPlayer.play(time - begin); + embeddedPlayerEvaluationInfo.entered = true; + } + } else if (entered) { + instantiatedPlayer.stop(); + embeddedPlayerEvaluationInfo.entered = false; + } + } + } + + public notifyHostSpeedChanged (speed: number) { + // Transmit the speed to embedded players that want a reconciled speed. + const { + _embeddedPlayers: embeddedPlayers, + _embeddedPlayerEvaluationInfos: embeddedPlayerEvaluationInfos, + } = this; + const nEmbeddedPlayers = embeddedPlayers.length; + for (let iEmbeddedPlayer = 0; iEmbeddedPlayer < nEmbeddedPlayers; ++iEmbeddedPlayer) { + const embeddedPlayerEvaluationInfo = embeddedPlayerEvaluationInfos[iEmbeddedPlayer]; + if (!embeddedPlayerEvaluationInfo) { + continue; + } + const { instantiatedPlayer } = embeddedPlayerEvaluationInfo; + const { reconciledSpeed } = embeddedPlayers[iEmbeddedPlayer]; + if (reconciledSpeed) { + instantiatedPlayer.setSpeed(speed); + } + } + } + + public notifyHostPlay (time: number) { + // Host has switched to "playing", this can be happened when: + // - Previous state is "stopped": we must have stopped all embedded players. + // - Is pausing: we need to resume all embedded players. + const { + _embeddedPlayers: embeddedPlayers, + _embeddedPlayerEvaluationInfos: embeddedPlayerEvaluationInfos, + } = this; + const nEmbeddedPlayers = embeddedPlayers.length; + for (let iEmbeddedPlayer = 0; iEmbeddedPlayer < nEmbeddedPlayers; ++iEmbeddedPlayer) { + const embeddedPlayerEvaluationInfo = embeddedPlayerEvaluationInfos[iEmbeddedPlayer]; + if (!embeddedPlayerEvaluationInfo) { + continue; + } + const { begin, end } = embeddedPlayers[iEmbeddedPlayer]; + const { instantiatedPlayer, entered } = embeddedPlayerEvaluationInfo; + if (entered) { + const { hostPauseTime } = embeddedPlayerEvaluationInfo; + // We can resume the embedded player + // only if the pause/play happened at the same time + // or the embedded player supports random access. + // Otherwise we have to say goodbye to that embedded player. + if (instantiatedPlayer.randomAccess || approx(hostPauseTime, time, 1e-5)) { + const startTime = clamp(time, begin, end); + instantiatedPlayer.play(startTime - begin); + } else { + instantiatedPlayer.stop(); + } + } + } + } + + public notifyHostPause (time: number) { + // Host is paused, simply transmit this to embedded players. + const { + _embeddedPlayers: embeddedPlayers, + _embeddedPlayerEvaluationInfos: embeddedPlayerEvaluationInfos, + } = this; + const nEmbeddedPlayers = embeddedPlayers.length; + for (let iEmbeddedPlayer = 0; iEmbeddedPlayer < nEmbeddedPlayers; ++iEmbeddedPlayer) { + const embeddedPlayerEvaluationInfo = embeddedPlayerEvaluationInfos[iEmbeddedPlayer]; + if (!embeddedPlayerEvaluationInfo) { + continue; + } + const { instantiatedPlayer, entered } = embeddedPlayerEvaluationInfo; + if (entered) { + instantiatedPlayer.pause(); + embeddedPlayerEvaluationInfo.hostPauseTime = time; + } + } + } + + public notifyHostStop () { + // Now that host is stopped, we stop all embedded players' playing + // regardless of their progresses. + const { + _embeddedPlayers: embeddedPlayers, + _embeddedPlayerEvaluationInfos: embeddedPlayerEvaluationInfos, + } = this; + const nEmbeddedPlayers = embeddedPlayers.length; + for (let iEmbeddedPlayer = 0; iEmbeddedPlayer < nEmbeddedPlayers; ++iEmbeddedPlayer) { + const embeddedPlayerEvaluationInfo = embeddedPlayerEvaluationInfos[iEmbeddedPlayer]; + if (!embeddedPlayerEvaluationInfo) { + continue; + } + const { instantiatedPlayer, entered } = embeddedPlayerEvaluationInfo; + if (entered) { + embeddedPlayerEvaluationInfo.entered = false; + instantiatedPlayer.stop(); + } + } + } + + private declare _embeddedPlayers: ReadonlyArray; + + private declare _embeddedPlayerEvaluationInfos: Array; +} + class AnimationClipEvaluation { constructor ( trackEvalStatuses: TrackEvalStatus[], exoticAnimationEvaluator: ExoticAnimationEvaluator | undefined, rootMotionEvaluation: RootMotionEvaluation | undefined, + embeddedPlayerEvaluation: EmbeddedPlayerEvaluation | undefined, ) { this._trackEvalStatues = trackEvalStatuses; this._exoticAnimationEvaluator = exoticAnimationEvaluator; this._rootMotionEvaluation = rootMotionEvaluation; + this._embeddedPlayerEvaluation = embeddedPlayerEvaluation; } /** @@ -876,6 +1085,7 @@ class AnimationClipEvaluation { const { _trackEvalStatues: trackEvalStatuses, _exoticAnimationEvaluator: exoticAnimationEvaluator, + _embeddedPlayerEvaluation: embeddedPlayerEvaluation, } = this; const nTrackEvalStatuses = trackEvalStatuses.length; @@ -888,6 +1098,36 @@ class AnimationClipEvaluation { if (exoticAnimationEvaluator) { exoticAnimationEvaluator.evaluate(time); } + + if (embeddedPlayerEvaluation) { + embeddedPlayerEvaluation.evaluate(time); + } + } + + public notifyHostSpeedChanged (value: number) { + this._embeddedPlayerEvaluation?.notifyHostSpeedChanged(value); + } + + /** + * Notifies that the host has ran into **playing** state. + * @param time The time where host ran into playing state. + */ + public notifyHostPlay (time: number) { + this._embeddedPlayerEvaluation?.notifyHostPlay(time); + } + + /** + * Notifies that the host has ran into **pause** state. + */ + public notifyHostPause (time: number) { + this._embeddedPlayerEvaluation?.notifyHostPause(time); + } + + /** + * Notifies that the host has ran into **stopped** state. + */ + public notifyHostStop () { + this._embeddedPlayerEvaluation?.notifyHostStop(); } /** @@ -905,6 +1145,7 @@ class AnimationClipEvaluation { private _exoticAnimationEvaluator: ExoticAnimationEvaluator | undefined; private _trackEvalStatues:TrackEvalStatus[] = []; private _rootMotionEvaluation: RootMotionEvaluation | undefined = undefined; + private _embeddedPlayerEvaluation: EmbeddedPlayerEvaluation | undefined = undefined; } class BoneTransform { diff --git a/cocos/core/animation/animation-state.ts b/cocos/core/animation/animation-state.ts index 49d412134f1..1a7d3ce9872 100644 --- a/cocos/core/animation/animation-state.ts +++ b/cocos/core/animation/animation-state.ts @@ -216,7 +216,14 @@ export class AnimationState extends Playable { * @zh 播放速率。 * @default: 1.0 */ - public speed = 1.0; + get speed () { + return this._speed; + } + + set speed (value) { + this._speed = value; + this._clipEval?.notifyHostSpeedChanged(value); + } /** * @en The current accumulated time of this animation in seconds. @@ -271,6 +278,7 @@ export class AnimationState extends Playable { protected _curveLoaded = false; private _clip: AnimationClip; + private _speed = 1.0; private _useSimpleProcess = false; private _target: Node | null = null; private _wrapMode = WrapMode.Normal; @@ -367,6 +375,8 @@ export class AnimationState extends Playable { if (!(EDITOR && !legacyCC.GAME_VIEW)) { this._clipEventEval = clip.createEventEvaluator(this._targetNode); } + + this._clipEval?.notifyHostSpeedChanged(this._speed); } public destroy () { @@ -494,6 +504,7 @@ export class AnimationState extends Playable { this._delayTime = this._delay; this._onReplayOrResume(); this.emit(EventType.PLAY, this); + this._clipEval?.notifyHostPlay(this.current); } protected onStop () { @@ -501,16 +512,19 @@ export class AnimationState extends Playable { this._onPauseOrStop(); } this.emit(EventType.STOP, this); + this._clipEval?.notifyHostStop(); } protected onResume () { this._onReplayOrResume(); this.emit(EventType.RESUME, this); + this._clipEval?.notifyHostPlay(this.current); } protected onPause () { this._onPauseOrStop(); this.emit(EventType.PAUSE, this); + this._clipEval?.notifyHostPause(this.current); } /** diff --git a/cocos/core/animation/animation.ts b/cocos/core/animation/animation.ts index 0182b5ec699..f2e37b64e26 100644 --- a/cocos/core/animation/animation.ts +++ b/cocos/core/animation/animation.ts @@ -23,6 +23,10 @@ THE SOFTWARE. */ +import './embedded-player/embedded-player'; +import './embedded-player/embedded-animation-clip-player'; +import './embedded-player/embedded-particle-system-player'; + export * from './target-path'; export * from './value-proxy'; export { UniformProxyFactory } from './value-proxy-factories/uniform'; diff --git a/cocos/core/animation/embedded-player/embedded-animation-clip-player.ts b/cocos/core/animation/embedded-player/embedded-animation-clip-player.ts new file mode 100644 index 00000000000..b7c69e82e59 --- /dev/null +++ b/cocos/core/animation/embedded-player/embedded-animation-clip-player.ts @@ -0,0 +1,93 @@ +import { ccclass, serializable } from 'cc.decorator'; +import { errorID } from '../../platform/debug'; +import type { Node } from '../../scene-graph/node'; +import { AnimationClip } from '../animation-clip'; +import { AnimationState } from '../animation-state'; +import { CLASS_NAME_PREFIX_ANIM } from '../define'; +import { EmbeddedPlayableState, EmbeddedPlayable } from './embedded-player'; + +/** + * @en + * The embedded animation clip playable. The playable play animation clip on a embedded player. + * @zh + * 动画剪辑子区域播放器。此播放器在子区域上播放动画剪辑。 + */ +@ccclass(`${CLASS_NAME_PREFIX_ANIM}EmbeddedAnimationClipPlayable`) +export class EmbeddedAnimationClipPlayable extends EmbeddedPlayable { + /** + * @en + * Path to the node onto which the animation clip would be played, relative from animation context root. + * @zh + * 要播放动画剪辑的节点的路径,相对于动画上下文的根节点。 + */ + @serializable + public path = ''; + + /** + * @en + * The animation clip to play. + * @zh + * 要播放的动画剪辑。 + */ + @serializable + public clip: AnimationClip | null = null; + + public instantiate (root: Node) { + const { clip, path } = this; + if (!clip) { + return null; + } + const clipRoot = root.getChildByPath(path); + if (!clipRoot) { + errorID(3938, path, root.getPathInHierarchy(), clip.name); + return null; + } + const state = new AnimationState(clip); + state.initialize( + clipRoot, + ); + return new EmbeddedAnimationClipPlayableState(state); + } +} + +class EmbeddedAnimationClipPlayableState extends EmbeddedPlayableState { + constructor (animationState: AnimationState) { + super(true); + this._animationState = animationState; + } + + public destroy (): void { + this._animationState.destroy(); + } + + /** + * Plays the animation state at specified time. + */ + public play (time: number): void { + this._animationState.play(); // Note play() rewinds the time to 0 + this._animationState.time = time; + } + + /** + * Pause the animation state. + */ + public pause (): void { + this._animationState.pause(); + } + + /** + * Stops the animation state. + */ + public stop (): void { + this._animationState.stop(); + } + + /** + * Sets the speed of the animation state. + */ + public setSpeed (speed: number): void { + this._animationState.speed = speed; + } + + private _animationState: AnimationState; +} diff --git a/cocos/core/animation/embedded-player/embedded-particle-system-player.ts b/cocos/core/animation/embedded-player/embedded-particle-system-player.ts new file mode 100644 index 00000000000..ab015b0a6b8 --- /dev/null +++ b/cocos/core/animation/embedded-player/embedded-particle-system-player.ts @@ -0,0 +1,88 @@ +import { ccclass, serializable } from 'cc.decorator'; +import type { ParticleSystem } from '../../../particle'; +import { warn } from '../../platform/debug'; +import type { Node } from '../../scene-graph/node'; +import { getClassByName } from '../../utils/js-typed'; +import { CLASS_NAME_PREFIX_ANIM } from '../define'; +import { EmbeddedPlayableState, EmbeddedPlayable } from './embedded-player'; + +/** + * @en + * The embedded particle system playable. The players play particle system on a embedded player. + * @zh + * 粒子系统子区域播放器。此播放器在子区域上播放粒子系统。 + */ +@ccclass(`${CLASS_NAME_PREFIX_ANIM}EmbeddedParticleSystemPlayable`) +export class EmbeddedParticleSystemPlayable extends EmbeddedPlayable { + /** + * @en + * Path to the node where particle system inhabits, relative from animation context root. + * @zh + * 粒子系统所在的结点路径,相对于动画上下文的根节点。 + */ + @serializable + public path = ''; + + public instantiate (root: Node) { + const node = root.getChildByPath(this.path); + if (!node) { + warn(`Hierarchy path ${this.path} does not exists.`); + return null; + } + // TODO: we shouldn't wanna know the name of `ParticleSystem` indeed. + const ParticleSystemConstructor = getClassByName(`cc.ParticleSystem`) as Constructor | undefined; + if (!ParticleSystemConstructor) { + warn(`Particle system is required for embedded particle system player.`); + return null; + } + const particleSystem = node.getComponent(ParticleSystemConstructor); + if (!particleSystem) { + warn(`${this.path} does not includes a particle system component.`); + return null; + } + return new EmbeddedParticleSystemPlayableState(particleSystem); + } +} + +class EmbeddedParticleSystemPlayableState extends EmbeddedPlayableState { + constructor (particleSystem: ParticleSystem) { + super(false); + this._particleSystem = particleSystem; + } + + public destroy (): void { + // DO NOTHING + } + + /** + * Plays the particle system from the beginning no matter current time. + * @param _time Ignored. + */ + public play (_time: number): void { + this._particleSystem.play(); + } + + /** + * Pause the particle system no matter current time. + */ + public pause (): void { + this._particleSystem.pause(); + } + + /** + * Stops the particle system. + */ + public stop (): void { + this._particleSystem.stopEmitting(); + } + + /** + * Sets the speed of the particle system. + * @param speed The speed. + */ + public setSpeed (speed: number): void { + this._particleSystem.simulationSpeed = speed; + } + + private _particleSystem: ParticleSystem; +} diff --git a/cocos/core/animation/embedded-player/embedded-player.ts b/cocos/core/animation/embedded-player/embedded-player.ts new file mode 100644 index 00000000000..3c19c018109 --- /dev/null +++ b/cocos/core/animation/embedded-player/embedded-player.ts @@ -0,0 +1,115 @@ +import { ccclass, serializable } from 'cc.decorator'; +import { EditorExtendable } from '../../data/editor-extendable'; +import type { Node } from '../../scene-graph'; +import { CLASS_NAME_PREFIX_ANIM } from '../define'; + +@ccclass(`${CLASS_NAME_PREFIX_ANIM}EmbeddedPlayer`) +export class EmbeddedPlayer extends EditorExtendable { + /** + * @en + * Begin time, in seconds. + * @zh + * 开始时间,以秒为单位。 + */ + @serializable + public begin = 0.0; + + /** + * @en + * End time, in seconds. + * @zh + * 结束时间,以秒为单位。 + */ + @serializable + public end = 0.0; + + /** + * @en + * Whether the speed of this embedded player should be reconciled with the host animation clip. + * @zh + * 子区域的播放速度是否应和宿主动画剪辑保持一致。 + */ + @serializable + public reconciledSpeed = false; + + /** + * @en + * Player of the embedded player. + * @zh + * 子区域的播放器。 + */ + @serializable + public playable: EmbeddedPlayable | null = null; +} + +export abstract class EmbeddedPlayable { + /** + * @en + * Instantiates this sub region. + * @zh + * 实例化此子区域。 + * @param root The root node of animation context. + * @internal + */ + public abstract instantiate(root: Node): EmbeddedPlayableState | null; +} + +export abstract class EmbeddedPlayableState { + constructor (randomAccess: boolean) { + this._randomAccess = randomAccess; + } + + /** + * @zh + * 是否可以随意调整此播放器到任何时间。 + * @en + * Indicates if this player can be adjusted to any time. + */ + public get randomAccess () { + return this._randomAccess; + } + + /** + * @zh + * 销毁此播放器。 + * @zh + * Destroys this player state. + */ + public abstract destroy (): void; + + /** + * @zh + * 该方法在此播放器开始播放时触发。 + * @en + * This method is called when this player gets to play. + * @param time Current time on the embedded player, relative to embedded player's start。 + */ + public abstract play(time: number): void; + + /** + * @zh + * 该方法在此播放器暂停播放时触发。 + * @en + * This method is called when this player pauses. + */ + public abstract pause(): void; + + /** + * @zh + * 该方法在此播放器结束播放时触发,或在宿主动画剪辑本身停止播放时触发。 + * @en + * This method is called when this player ends its playback, and is called when the host animation clip is stopped. + */ + public abstract stop(): void; + + /** + * @zh + * 如果 [[`EmbeddedPlayer.reconciledSpeed`]] 为 `true`,则在宿主的播放速度改变时触发。 + * @en + * If [[`EmbeddedPlayer.reconciledSpeed`]] is `true`, is called when the host changes its speed. + * @param speed The speed. + */ + public abstract setSpeed(speed: number): void; + + private declare _randomAccess: boolean; +} diff --git a/cocos/core/assets/image-asset.jsb.ts b/cocos/core/assets/image-asset.jsb.ts index 25faefd8e0c..7a5af978ee1 100644 --- a/cocos/core/assets/image-asset.jsb.ts +++ b/cocos/core/assets/image-asset.jsb.ts @@ -27,7 +27,7 @@ import { ALIPAY, XIAOMI, JSB, TEST, BAIDU } from 'internal:constants'; import { Format, FormatFeatureBit } from '../gfx'; import { legacyCC } from '../global-exports'; import { PixelFormat } from './asset-enum'; -import { warnID } from '../platform'; +import { macro, sys, warnID } from '../platform'; export type ImageAsset = jsb.ImageAsset; export const ImageAsset = jsb.ImageAsset; @@ -45,7 +45,7 @@ export type ImageSource = HTMLCanvasElement | HTMLImageElement | IMemoryImageSou const extnames = ['.png', '.jpg', '.jpeg', '.bmp', '.webp', '.pvr', '.pkm', '.astc']; function isImageBitmap (imageSource: any): boolean { - return !!(legacyCC.sys.hasFeature(legacyCC.sys.Feature.IMAGE_BITMAP) && imageSource instanceof ImageBitmap); + return !!(sys.hasFeature(sys.Feature.IMAGE_BITMAP) && imageSource instanceof ImageBitmap); } function isNativeImage (imageSource: ImageSource): imageSource is (HTMLImageElement | HTMLCanvasElement | ImageBitmap) { @@ -213,7 +213,7 @@ imageAssetProto._deserialize = function (data: any) { // let format = this._format; let format = this.format; let ext = ''; - const SupportTextureFormats = legacyCC.macro.SUPPORT_TEXTURE_FORMATS as string[]; + const SupportTextureFormats = macro.SUPPORT_TEXTURE_FORMATS as string[]; for (const extensionID of extensionIDs) { const extFormat = extensionID.split('@'); @@ -237,7 +237,7 @@ imageAssetProto._deserialize = function (data: any) { } else if ((fmt === PixelFormat.RGB_ETC2 || fmt === PixelFormat.RGBA_ETC2) && (!device || !(device.getFormatFeatures(Format.ETC2_RGB8) & FormatFeatureBit.SAMPLED_TEXTURE))) { continue; - } else if (tmpExt === '.webp' && !legacyCC.sys.hasFeature(legacyCC.sys.Feature.WEBP)) { + } else if (tmpExt === '.webp' && !sys.hasFeature(sys.Feature.WEBP)) { continue; } preferedExtensionIndex = index; diff --git a/cocos/core/assets/image-asset.ts b/cocos/core/assets/image-asset.ts index 85746d30911..a21ce5edb79 100644 --- a/cocos/core/assets/image-asset.ts +++ b/cocos/core/assets/image-asset.ts @@ -25,12 +25,14 @@ // @ts-check import { ccclass, override } from 'cc.decorator'; -import { EDITOR, MINIGAME, ALIPAY, XIAOMI, JSB, TEST, BAIDU } from 'internal:constants'; -import { Device, Feature, Format, FormatFeatureBit } from '../gfx'; +import { EDITOR, ALIPAY, XIAOMI, JSB, TEST, BAIDU } from 'internal:constants'; +import { Device, Format, FormatFeatureBit } from '../gfx'; import { Asset } from './asset'; import { PixelFormat } from './asset-enum'; import { legacyCC } from '../global-exports'; import { warnID } from '../platform/debug'; +import { macro } from '../platform/macro'; +import { sys } from '../platform/sys'; /** * @en Image source in memory @@ -51,7 +53,7 @@ export interface IMemoryImageSource { export type ImageSource = HTMLCanvasElement | HTMLImageElement | IMemoryImageSource | ImageBitmap; function isImageBitmap (imageSource: any): boolean { - return !!(legacyCC.sys.hasFeature(legacyCC.sys.Feature.IMAGE_BITMAP) && imageSource instanceof ImageBitmap); + return !!(sys.hasFeature(sys.Feature.IMAGE_BITMAP) && imageSource instanceof ImageBitmap); } function fetchImageSource (imageSource: ImageSource) { @@ -259,7 +261,7 @@ export class ImageAsset extends Asset { let preferedExtensionIndex = Number.MAX_VALUE; let format = this._format; let ext = ''; - const SupportTextureFormats = legacyCC.macro.SUPPORT_TEXTURE_FORMATS as string[]; + const SupportTextureFormats = macro.SUPPORT_TEXTURE_FORMATS; for (const extensionID of extensionIDs) { const extFormat = extensionID.split('@'); @@ -280,7 +282,7 @@ export class ImageAsset extends Asset { } else if ((fmt === PixelFormat.RGB_ETC2 || fmt === PixelFormat.RGBA_ETC2) && (!device || !(device.getFormatFeatures(Format.ETC2_RGB8) & FormatFeatureBit.SAMPLED_TEXTURE))) { continue; - } else if (tmpExt === '.webp' && !legacyCC.sys.hasFeature(legacyCC.sys.Feature.WEBP)) { + } else if (tmpExt === '.webp' && !sys.hasFeature(sys.Feature.WEBP)) { continue; } preferedExtensionIndex = index; diff --git a/cocos/core/assets/index.jsb.ts b/cocos/core/assets/index.jsb.ts index 6d2cbf4c6fd..5fdc8930b17 100644 --- a/cocos/core/assets/index.jsb.ts +++ b/cocos/core/assets/index.jsb.ts @@ -24,10 +24,6 @@ THE SOFTWARE. */ -/** - * @packageDocumentation - * @hidden - */ import './deprecation'; export { Asset } from './asset'; diff --git a/cocos/core/assets/material.jsb.ts b/cocos/core/assets/material.jsb.ts index 39d6ff3160a..888b3944954 100644 --- a/cocos/core/assets/material.jsb.ts +++ b/cocos/core/assets/material.jsb.ts @@ -23,10 +23,6 @@ THE SOFTWARE. */ -/** - * @packageDocumentation - * @module material - */ import { EffectAsset } from './effect-asset'; import { Texture } from '../gfx'; import { TextureBase } from './texture-base'; diff --git a/cocos/core/builtin/effects.ts b/cocos/core/builtin/effects.ts index 8a08b2d2048..98e6acb5a41 100644 --- a/cocos/core/builtin/effects.ts +++ b/cocos/core/builtin/effects.ts @@ -603,11 +603,11 @@ export const effects = [ "shaders": [ { "name": "standard|standard-vs|standard-fs", - "hash": 56627744, + "hash": 3591917274, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 286, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 128 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 196, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 128 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }, { "name": "CCShadow", "defines": [] }], "samplerTextures": [{ "name": "cc_shadowMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_spotLightingMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_environment", "defines": ["CC_USE_IBL"] }, { "name": "cc_diffuseMap", "defines": ["CC_USE_DIFFUSEMAP"] }], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }, { "name": "CCForwardLight", "defines": ["CC_FORWARD_ADD", "CC_ENABLE_CLUSTERED_LIGHT_CULLING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_lightingMap", "defines": ["CC_USE_LIGHTMAP", "!USE_BATCHING", "!CC_FORWARD_ADD"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }, { "name": "CCForwardLight", "defines": ["CC_FORWARD_ADD", "CC_ENABLE_CLUSTERED_LIGHT_CULLING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }, { "name": "cc_lightingMap", "defines": ["CC_USE_LIGHTMAP", "!USE_BATCHING", "!CC_FORWARD_ADD"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -622,6 +622,7 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" }, { "name": "CC_USE_FOG", "type": "number", "range": [0, 4] }, { "name": "CC_USE_ACCURATE_FOG", "type": "boolean" }, { "name": "USE_VERTEX_COLOR", "type": "boolean" }, @@ -697,11 +698,11 @@ export const effects = [ }, { "name": "standard|shadow-caster-vs:vert|shadow-caster-fs:frag", - "hash": 2647187139, + "hash": 3398834153, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 242, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 128 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 152, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 128 }, "globals": { "blocks": [{ "name": "CCShadow", "defines": [] }, { "name": "CCGlobal", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "CCCamera", "defines": ["CC_RECEIVE_SHADOW"] }], "samplerTextures": [{ "name": "cc_shadowMap", "defines": ["CC_RECEIVE_SHADOW"] }, { "name": "cc_spotLightingMap", "defines": ["CC_RECEIVE_SHADOW"] }], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -716,6 +717,7 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" }, { "name": "HAS_SECOND_UV", "type": "boolean" }, { "name": "USE_ALBEDO_MAP", "type": "boolean" }, { "name": "ALBEDO_UV", "type": "string", "options": ["v_uv", "v_uv1"] }, @@ -861,11 +863,11 @@ export const effects = [ "shaders": [ { "name": "unlit|unlit-vs:vert|unlit-fs:frag", - "hash": 2175084560, + "hash": 3608581236, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 203, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 46 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 113, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 46 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -880,6 +882,7 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" }, { "name": "CC_USE_FOG", "type": "number", "range": [0, 4] }, { "name": "CC_USE_ACCURATE_FOG", "type": "boolean" }, { "name": "USE_VERTEX_COLOR", "type": "boolean" }, @@ -934,11 +937,11 @@ export const effects = [ "shaders": [ { "name": "bloom|bloom-vs|prefilter-fs", - "hash": 1438305237, + "hash": 3484556824, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 152, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 45 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 62, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 45 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -952,7 +955,8 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, - { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" } + { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" } ], "attributes": [ { "name": "a_position", "defines": [], "format": 32, "location": 0 }, @@ -986,11 +990,11 @@ export const effects = [ }, { "name": "bloom|bloom-vs|downsample-fs", - "hash": 3008014650, + "hash": 25210646, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 152, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 45 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 62, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 45 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -1004,7 +1008,8 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, - { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" } + { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" } ], "attributes": [ { "name": "a_position", "defines": [], "format": 32, "location": 0 }, @@ -1038,11 +1043,11 @@ export const effects = [ }, { "name": "bloom|bloom-vs|upsample-fs", - "hash": 2509006203, + "hash": 1340179983, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 152, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 45 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 62, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 45 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -1056,7 +1061,8 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, - { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" } + { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" } ], "attributes": [ { "name": "a_position", "defines": [], "format": 32, "location": 0 }, @@ -1090,11 +1096,11 @@ export const effects = [ }, { "name": "bloom|bloom-vs|combine-fs", - "hash": 3368363993, + "hash": 985336304, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 152, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 45 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 62, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 45 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -1108,7 +1114,8 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, - { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" } + { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" } ], "attributes": [ { "name": "a_position", "defines": [], "format": 32, "location": 0 }, @@ -1218,11 +1225,11 @@ export const effects = [ "shaders": [ { "name": "planar-shadow|planar-shadow-vs:vert|planar-shadow-fs:frag", - "hash": 945434018, + "hash": 2489631761, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 280, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 122 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 190, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 122 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }, { "name": "CCShadow", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }, { "name": "CCLocalBatched", "defines": ["!USE_INSTANCING", "USE_BATCHING"] }, { "name": "CCLocal", "defines": ["!USE_INSTANCING", "!USE_BATCHING"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -1236,7 +1243,8 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_POSITION", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, - { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" } + { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" } ], "attributes": [ { "name": "a_position", "defines": [], "format": 32, "location": 0 }, @@ -1272,11 +1280,11 @@ export const effects = [ "shaders": [ { "name": "post-process|post-process-vs|post-process-fs", - "hash": 761897287, + "hash": 2821682086, "builtins": { - "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 152, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 44 }, + "statistics": { "CC_EFFECT_USED_VERTEX_UNIFORM_VECTORS": 62, "CC_EFFECT_USED_FRAGMENT_UNIFORM_VECTORS": 44 }, "globals": { "blocks": [{ "name": "CCGlobal", "defines": [] }, { "name": "CCCamera", "defines": [] }], "samplerTextures": [], "buffers": [], "images": [] }, - "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }], "buffers": [], "images": [] } + "locals": { "blocks": [{ "name": "CCMorph", "defines": ["CC_USE_MORPH"] }, { "name": "CCSkinningTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinningAnimation", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "CCSkinning", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "!CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "samplerTextures": [{ "name": "cc_PositionDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_POSITION"] }, { "name": "cc_NormalDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_NORMAL"] }, { "name": "cc_TangentDisplacements", "defines": ["CC_USE_MORPH", "CC_MORPH_TARGET_HAS_TANGENT"] }, { "name": "cc_jointTexture", "defines": ["CC_USE_SKINNING", "CC_USE_BAKED_ANIMATION"] }, { "name": "cc_realtimeJoint", "defines": ["CC_USE_SKINNING", "!CC_USE_BAKED_ANIMATION", "CC_USE_REAL_TIME_JOINT_TEXTURE"] }], "buffers": [], "images": [] } }, "defines": [ { "name": "USE_INSTANCING", "type": "boolean" }, @@ -1291,6 +1299,7 @@ export const effects = [ { "name": "CC_MORPH_TARGET_HAS_NORMAL", "type": "boolean" }, { "name": "CC_MORPH_TARGET_HAS_TANGENT", "type": "boolean" }, { "name": "CC_MORPH_PRECOMPUTED", "type": "boolean" }, + { "name": "CC_USE_REAL_TIME_JOINT_TEXTURE", "type": "boolean" }, { "name": "ANTIALIAS_TYPE", "type": "number", "range": [0, 3] } ], "attributes": [ diff --git a/cocos/core/builtin/shader-sources/glsl1.ts b/cocos/core/builtin/shader-sources/glsl1.ts index 0a41f585052..a5be2d4723f 100644 --- a/cocos/core/builtin/shader-sources/glsl1.ts +++ b/cocos/core/builtin/shader-sources/glsl1.ts @@ -88,11 +88,11 @@ export const glsl1 = [ ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matWorldIT;\nuniform highp vec4 cc_lightingMapUVParam;\nuniform highp vec4 cc_localShadowBias;\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nuniform vec4 tilingOffset;\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nvarying highp vec4 v_shadowPos;\nuniform highp mat4 cc_matLightViewProj;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#elif !USE_BATCHING\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_shadowWHPBInfo.w, cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nattribute vec4 a_color;\nvarying lowp vec4 v_color;\n#endif\nvarying vec3 v_position;\nvarying mediump vec3 v_normal;\nvarying vec2 v_uv;\n#if HAS_SECOND_UV\nvarying mediump vec2 v_uv1;\n#endif\n#if CC_RECEIVE_SHADOW\nvarying mediump vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvarying mediump vec4 v_tangent;\n#endif\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nattribute vec2 a_texCoord1;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_tangent.w = In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matWorldIT;\nuniform highp vec4 cc_lightingMapUVParam;\nuniform highp vec4 cc_localShadowBias;\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nuniform vec4 tilingOffset;\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nvarying highp vec4 v_shadowPos;\nuniform highp mat4 cc_matLightViewProj;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#elif !USE_BATCHING\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_shadowWHPBInfo.w, cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nattribute vec4 a_color;\nvarying lowp vec4 v_color;\n#endif\nvarying vec3 v_position;\nvarying mediump vec3 v_normal;\nvarying vec2 v_uv;\n#if HAS_SECOND_UV\nvarying mediump vec2 v_uv1;\n#endif\n#if CC_RECEIVE_SHADOW\nvarying mediump vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvarying mediump vec4 v_tangent;\n#endif\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nattribute vec2 a_texCoord1;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_tangent.w = In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", "frag": "\n#ifdef GL_EXT_draw_buffers\n#extension GL_EXT_draw_buffers: enable\n#endif\n#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives: enable\n#endif\n#ifdef GL_EXT_shader_texture_lod\n#extension GL_EXT_shader_texture_lod: enable\n#endif\nprecision highp float;\nuniform highp mat4 cc_matView;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\nuniform mediump vec4 cc_mainLitColor;\nuniform mediump vec4 cc_ambientSky;\nuniform mediump vec4 cc_ambientGround;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\nuniform mediump vec4 cc_nearFar;\nuniform mediump vec4 cc_viewPort;\nuniform vec4 albedo;\nuniform vec4 albedoScaleAndCutoff;\nuniform vec4 pbrParams;\nuniform vec4 emissive;\nuniform vec4 emissiveScaleParam;\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nuniform highp mat4 cc_matLightView;\nuniform highp vec4 cc_shadowInvProjDepthInfo;\nuniform highp vec4 cc_shadowProjDepthInfo;\nuniform highp vec4 cc_shadowProjInfo;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowWHPBInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\nuniform highp mat4 cc_matCSMView[4];\nuniform highp mat4 cc_matCSMViewProj[4];\nuniform highp mat4 cc_matCSMViewProjAtlas[4];\nuniform highp vec4 cc_csmProjDepthInfo[4];\nuniform highp vec4 cc_csmProjInfo[4];\nuniform highp vec4 cc_csmInfo;\nfloat GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\nfloat dist = length(viewPos);\nreturn (dist - near) / (far - near);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn GetLinearDepthFromViewSpace(viewStartPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nfloat NativePCFShadowFactorHard (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\n#if CC_SHADOWMAP_FORMAT == 1\nreturn step(shadowNDCPos.z, dot(texture2D(shadowMap, shadowNDCPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nreturn step(shadowNDCPos.z, texture2D(shadowMap, shadowNDCPos.xy).x);\n#endif\n}\nfloat NativePCFShadowFactorSoft (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nvec2 shadowNDCPos_offset = shadowNDCPos.xy + oneTap;\nfloat block0, block1, block2, block3;\n#if CC_SHADOWMAP_FORMAT == 1\nblock0 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock0 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\nblock1 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)).x);\nblock2 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)).x);\nblock3 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)).x);\n#endif\nfloat coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nfloat shadowNDCPos_offset_L = shadowNDCPos.x - oneTap.x;\nfloat shadowNDCPos_offset_R = shadowNDCPos.x + oneTap.x;\nfloat shadowNDCPos_offset_U = shadowNDCPos.y - oneTap.y;\nfloat shadowNDCPos_offset_D = shadowNDCPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\n#if CC_SHADOWMAP_FORMAT == 1\nblock0 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(shadowNDCPos.z, dot(texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock0 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)).x);\nblock1 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)).x);\nblock2 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)).x);\nblock3 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)).x);\nblock4 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\nblock5 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)).x);\nblock6 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)).x);\nblock7 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)).x);\nblock8 = step(shadowNDCPos.z, texture2D(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)).x);\n#endif\nfloat coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\nfloat coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat NativePCFShadowFactorSoft5X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nvec2 twoTap = oneTap * 2.0;\nvec2 offset1 = shadowNDCPos.xy + vec2(-twoTap.x, -twoTap.y);\nvec2 offset2 = shadowNDCPos.xy + vec2(-oneTap.x, -twoTap.y);\nvec2 offset3 = shadowNDCPos.xy + vec2(0.0, -twoTap.y);\nvec2 offset4 = shadowNDCPos.xy + vec2(oneTap.x, -twoTap.y);\nvec2 offset5 = shadowNDCPos.xy + vec2(twoTap.x, -twoTap.y);\nvec2 offset6 = shadowNDCPos.xy + vec2(-twoTap.x, -oneTap.y);\nvec2 offset7 = shadowNDCPos.xy + vec2(-oneTap.x, -oneTap.y);\nvec2 offset8 = shadowNDCPos.xy + vec2(0.0, -oneTap.y);\nvec2 offset9 = shadowNDCPos.xy + vec2(oneTap.x, -oneTap.y);\nvec2 offset10 = shadowNDCPos.xy + vec2(twoTap.x, -oneTap.y);\nvec2 offset11 = shadowNDCPos.xy + vec2(-twoTap.x, 0.0);\nvec2 offset12 = shadowNDCPos.xy + vec2(-oneTap.x, 0.0);\nvec2 offset13 = shadowNDCPos.xy + vec2(0.0, 0.0);\nvec2 offset14 = shadowNDCPos.xy + vec2(oneTap.x, 0.0);\nvec2 offset15 = shadowNDCPos.xy + vec2(twoTap.x, 0.0);\nvec2 offset16 = shadowNDCPos.xy + vec2(-twoTap.x, oneTap.y);\nvec2 offset17 = shadowNDCPos.xy + vec2(-oneTap.x, oneTap.y);\nvec2 offset18 = shadowNDCPos.xy + vec2(0.0, oneTap.y);\nvec2 offset19 = shadowNDCPos.xy + vec2(oneTap.x, oneTap.y);\nvec2 offset20 = shadowNDCPos.xy + vec2(twoTap.x, oneTap.y);\nvec2 offset21 = shadowNDCPos.xy + vec2(-twoTap.x, twoTap.y);\nvec2 offset22 = shadowNDCPos.xy + vec2(-oneTap.x, twoTap.y);\nvec2 offset23 = shadowNDCPos.xy + vec2(0.0, twoTap.y);\nvec2 offset24 = shadowNDCPos.xy + vec2(oneTap.x, twoTap.y);\nvec2 offset25 = shadowNDCPos.xy + vec2(twoTap.x, twoTap.y);\nfloat block1, block2, block3, block4, block5, block6, block7, block8, block9, block10, block11, block12, block13, block14, block15, block16, block17, block18, block19, block20, block21, block22, block23, block24, block25;\n#if CC_SHADOWMAP_FORMAT == 1\nblock1 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset1), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset2), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset3), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset4), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset5), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset6), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset7), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset8), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock9 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset9), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock10 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset10), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock11 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset11), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock12 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset12), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock13 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset13), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock14 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset14), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock15 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset15), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock16 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset16), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock17 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset17), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock18 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset18), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock19 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset19), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock20 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset20), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock21 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset21), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock22 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset22), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock23 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset23), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock24 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset24), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock25 = step(shadowNDCPos.z, dot(texture2D(shadowMap, offset25), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock1 = step(shadowNDCPos.z, texture2D(shadowMap, offset1).x);\nblock2 = step(shadowNDCPos.z, texture2D(shadowMap, offset2).x);\nblock3 = step(shadowNDCPos.z, texture2D(shadowMap, offset3).x);\nblock4 = step(shadowNDCPos.z, texture2D(shadowMap, offset4).x);\nblock5 = step(shadowNDCPos.z, texture2D(shadowMap, offset5).x);\nblock6 = step(shadowNDCPos.z, texture2D(shadowMap, offset6).x);\nblock7 = step(shadowNDCPos.z, texture2D(shadowMap, offset7).x);\nblock8 = step(shadowNDCPos.z, texture2D(shadowMap, offset8).x);\nblock9 = step(shadowNDCPos.z, texture2D(shadowMap, offset9).x);\nblock10 = step(shadowNDCPos.z, texture2D(shadowMap, offset10).x);\nblock11 = step(shadowNDCPos.z, texture2D(shadowMap, offset11).x);\nblock12 = step(shadowNDCPos.z, texture2D(shadowMap, offset12).x);\nblock13 = step(shadowNDCPos.z, texture2D(shadowMap, offset13).x);\nblock14 = step(shadowNDCPos.z, texture2D(shadowMap, offset14).x);\nblock15 = step(shadowNDCPos.z, texture2D(shadowMap, offset15).x);\nblock16 = step(shadowNDCPos.z, texture2D(shadowMap, offset16).x);\nblock17 = step(shadowNDCPos.z, texture2D(shadowMap, offset17).x);\nblock18 = step(shadowNDCPos.z, texture2D(shadowMap, offset18).x);\nblock19 = step(shadowNDCPos.z, texture2D(shadowMap, offset19).x);\nblock20 = step(shadowNDCPos.z, texture2D(shadowMap, offset20).x);\nblock21 = step(shadowNDCPos.z, texture2D(shadowMap, offset21).x);\nblock22 = step(shadowNDCPos.z, texture2D(shadowMap, offset22).x);\nblock23 = step(shadowNDCPos.z, texture2D(shadowMap, offset23).x);\nblock24 = step(shadowNDCPos.z, texture2D(shadowMap, offset24).x);\nblock25 = step(shadowNDCPos.z, texture2D(shadowMap, offset25).x);\n#endif\nvec2 coef = fract(shadowNDCPos.xy * shadowMapResolution);\nvec2 v1X1 = mix(vec2(block1, block6), vec2(block2, block7), coef.xx);\nvec2 v1X2 = mix(vec2(block2, block7), vec2(block3, block8), coef.xx);\nvec2 v1X3 = mix(vec2(block3, block8), vec2(block4, block9), coef.xx);\nvec2 v1X4 = mix(vec2(block4, block9), vec2(block5, block10), coef.xx);\nfloat v1 = mix(v1X1.x, v1X1.y, coef.y) + mix(v1X2.x, v1X2.y, coef.y) + mix(v1X3.x, v1X3.y, coef.y) + mix(v1X4.x, v1X4.y, coef.y);\nvec2 v2X1 = mix(vec2(block6, block11), vec2(block7, block12), coef.xx);\nvec2 v2X2 = mix(vec2(block7, block12), vec2(block8, block13), coef.xx);\nvec2 v2X3 = mix(vec2(block8, block13), vec2(block9, block14), coef.xx);\nvec2 v2X4 = mix(vec2(block9, block14), vec2(block10, block15), coef.xx);\nfloat v2 = mix(v2X1.x, v2X1.y, coef.y) + mix(v2X2.x, v2X2.y, coef.y) + mix(v2X3.x, v2X3.y, coef.y) + mix(v2X4.x, v2X4.y, coef.y);\nvec2 v3X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\nvec2 v3X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\nvec2 v3X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\nvec2 v3X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\nfloat v3 = mix(v3X1.x, v3X1.y, coef.y) + mix(v3X2.x, v3X2.y, coef.y) + mix(v3X3.x, v3X3.y, coef.y) + mix(v3X4.x, v3X4.y, coef.y);\nvec2 v4X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\nvec2 v4X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\nvec2 v4X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\nvec2 v4X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\nfloat v4 = mix(v4X1.x, v4X1.y, coef.y) + mix(v4X2.x, v4X2.y, coef.y) + mix(v4X3.x, v4X3.y, coef.y) + mix(v4X4.x, v4X4.y, coef.y);\nvec2 v5X1 = mix(vec2(block16, block21), vec2(block17, block22), coef.xx);\nvec2 v5X2 = mix(vec2(block17, block22), vec2(block18, block23), coef.xx);\nvec2 v5X3 = mix(vec2(block18, block23), vec2(block19, block24), coef.xx);\nvec2 v5X4 = mix(vec2(block19, block24), vec2(block20, block25), coef.xx);\nfloat v5 = mix(v5X1.x, v5X1.y, coef.y) + mix(v5X2.x, v5X2.y, coef.y) + mix(v5X3.x, v5X3.y, coef.y) + mix(v5X4.x, v5X4.y, coef.y);\nfloat fAvg = (v1 + v2 + v3 + v4 + v5) * 0.05;\nreturn fAvg;\n}\nbool GetShadowNDCPos(out vec3 shadowNDCPos, vec4 shadowPosWithDepthBias)\n{\nshadowNDCPos = shadowPosWithDepthBias.xyz / shadowPosWithDepthBias.w * 0.5 + 0.5;\nif (shadowNDCPos.x < 0.0 || shadowNDCPos.x > 1.0 ||\nshadowNDCPos.y < 0.0 || shadowNDCPos.y > 1.0 ||\nshadowNDCPos.z < 0.0 || shadowNDCPos.z > 1.0) {\nreturn false;\n}\nshadowNDCPos.xy = cc_cameraPos.w == 1.0 ? vec2(shadowNDCPos.xy.x, 1.0 - shadowNDCPos.xy.y) : shadowNDCPos.xy;\nreturn true;\n}\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, mat4 matLightView, vec2 projScaleXY)\n{\nvec4 newShadowPos = shadowPos;\nif (normalBias > EPSILON_LOWP)\n{\nvec4 viewNormal = matLightView * vec4(worldNormal, 0.0);\nif (viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > EPSILON) {\nclipSpacePos.z = GetLinearDepthFromViewSpace(viewSpacePos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias, float projScaleZ, float projBiasZ)\n{\nfloat coeffA = projScaleZ;\nfloat coeffB = projBiasZ;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetDirLightShadowFactorHard (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorHard(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft3X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft5X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorHard(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft3X(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft5X(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nvec4 pos = ApplyShadowDepthBias_Perspective(shadowPos, shadowBias.x);\nif (pcf > 2.9) {\nreturn CCGetSpotLightShadowFactorSoft5X(pos, worldPos);\n} else if (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft3X(pos, worldPos);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(pos, worldPos);\n}else {\nreturn CCGetSpotLightShadowFactorHard(pos, worldPos);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y, cc_matLightView, cc_shadowProjInfo.xy);\npos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 2.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n} else if (pcf > 1.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n}else {\nrealtimeShadow = CCGetDirLightShadowFactorHard(pos);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\nint CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out mat4 matShadowView, vec3 worldPos) {\nfor (int i = 0; i < 4; i++) {\nvec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\nvec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;\nif (clipPos.x < (0.0 + cc_csmInfo.y) || clipPos.x > (1.0 - cc_csmInfo.y) ||\nclipPos.y < (0.0 + cc_csmInfo.y) || clipPos.y > (1.0 - cc_csmInfo.y) ||\nclipPos.z < 0.0 || clipPos.z > 1.0) {\ncontinue;\n}\ncsmPos = cc_matCSMViewProjAtlas[i] * vec4(worldPos.xyz, 1.0);\nshadowProjDepthInfo = cc_csmProjDepthInfo[i];\nshadowProjInfo = cc_csmProjInfo[i];\nmatShadowView = cc_matCSMView[i];\nreturn i;\n}\nreturn -1;\n}\nfloat CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias)\n{\nvec4 csmPos = vec4(1.0);\nvec4 shadowProjDepthInfo, shadowProjInfo;\nmat4 matLightView;\nint level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, matLightView, worldPos);\nif (level < 0) { return 1.0; }\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(csmPos, N, shadowBias.y, matLightView, shadowProjInfo.xy);\npos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, shadowProjDepthInfo.x, shadowProjDepthInfo.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 2.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n} else if (pcf > 1.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n} else if (pcf > 0.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n}else {\nrealtimeShadow = CCGetDirLightShadowFactorHard(pos);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn texture2DLodEXT(tex, coord, lod);\n#else\nreturn texture2D(tex, coord, lod);\n#endif\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\n#ifdef GL_EXT_shader_texture_lod\nreturn textureCubeLodEXT(tex, coord, lod);\n#else\nreturn textureCube(tex, coord, lod);\n#endif\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = textureCube(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\nfloat specularIntensity;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.08 * s.specularIntensity), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nif (cc_shadowLPNNInfo.w > 0.0) {\nshadow = CCCSMFactorBase(position, N, s.shadowBias);\n} else {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > EPSILON_LOWP) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = textureCube(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nvarying highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvarying vec3 v_luv;\nuniform sampler2D cc_lightingMap;\n#endif\nvarying vec3 v_position;\nvarying vec2 v_uv;\n#if HAS_SECOND_UV\nvarying mediump vec2 v_uv1;\n#endif\nvarying mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nvarying mediump vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nvarying lowp vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nvarying mediump vec4 v_tangent;\nuniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nuniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nuniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nuniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nuniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture2D(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture2D(cc_lightingMap, v_luv.xy);\ns.lightmap = lightColor.xyz * v_luv.z;\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture2D(normalMap, NORMAL_UV).xyz - vec3(0.5);\nvec3 bitangent = cross(v_normal, v_tangent.xyz) * v_tangent.w;\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent.xyz) +\n(nmmp.y * emissiveScaleParam.w) * normalize(bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture2D(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture2D(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture2D(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.specularIntensity = 0.5;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture2D(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\n#if CC_PIPELINE_TYPE == 0\n#define LIGHTS_PER_PASS 1\n#else\n#define LIGHTS_PER_PASS 10\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nuniform highp vec4 cc_lightPos[LIGHTS_PER_PASS];\nuniform vec4 cc_lightColor[LIGHTS_PER_PASS];\nuniform vec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nuniform vec4 cc_lightDir[LIGHTS_PER_PASS];\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nreadonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nreadonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nreadonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\ngl_FragData[0] = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nvoid main () {\nStandardSurface s; surf(s);\ngl_FragData[0] = s.albedo;\ngl_FragData[1] = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\ngl_FragData[2] = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matWorldIT;\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nuniform vec4 tilingOffset;\nuniform highp mat4 cc_matLightViewProj;\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nattribute vec2 a_texCoord1;\n#endif\nvarying vec2 v_uv;\n#if HAS_SECOND_UV\nvarying vec2 v_uv1;\n#endif\nvarying vec4 v_worldPos;\nvarying float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\nuniform highp mat4 cc_matWorldIT;\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nuniform vec4 tilingOffset;\nuniform highp mat4 cc_matLightViewProj;\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nattribute vec2 a_texCoord1;\n#endif\nvarying vec2 v_uv;\n#if HAS_SECOND_UV\nvarying vec2 v_uv1;\n#endif\nvarying vec4 v_worldPos;\nvarying float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nuniform vec4 albedo;\nuniform vec4 albedoScaleAndCutoff;\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nuniform highp mat4 cc_matLightView;\nuniform mediump vec4 cc_shadowNFLSInfo;\nuniform mediump vec4 cc_shadowLPNNInfo;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nfloat GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\nfloat dist = length(viewPos);\nreturn (dist - near) / (far - near);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn GetLinearDepthFromViewSpace(viewStartPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\nvarying vec2 v_uv;\n#if HAS_SECOND_UV\nvarying vec2 v_uv1;\n#endif\nvarying vec4 v_worldPos;\nvarying float v_clip_depth;\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture2D(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nvoid main() { gl_FragColor = frag(); }", } ], @@ -108,25 +108,25 @@ export const glsl1 = [ ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nattribute lowp vec4 a_color;\nvarying lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nvarying vec2 v_uv;\nuniform vec4 tilingOffset;\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nattribute lowp vec4 a_color;\nvarying lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nvarying vec2 v_uv;\nuniform vec4 tilingOffset;\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_fogColor;\nuniform mediump vec4 cc_fogBase;\nuniform mediump vec4 cc_fogAdd;\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nvarying float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#if USE_ALPHA_TEST\n#endif\n#if USE_TEXTURE\nvarying vec2 v_uv;\nuniform sampler2D mainTexture;\n#endif\nuniform vec4 mainColor;\nuniform vec4 colorScaleAndCutoff;\n#if USE_VERTEX_COLOR\nvarying lowp vec4 v_color;\n#endif\nvec4 frag () {\nvec4 o = mainColor;\no.rgb *= colorScaleAndCutoff.xyz;\n#if USE_VERTEX_COLOR\no.rgb *= SRGBToLinear(v_color.rgb);\no.a *= v_color.a;\n#endif\n#if USE_TEXTURE\nvec4 texColor = texture2D(mainTexture, v_uv);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\no *= texColor;\n#endif\n#if USE_ALPHA_TEST\nif (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;\n#endif\nCC_APPLY_FOG(o);\nreturn CCFragOutput(o);\n}\nvoid main() { gl_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvarying vec2 v_uv;\nuniform mediump vec4 texSize;\nuniform sampler2D outputResultMap;\nfloat luminance(vec3 color) {\nreturn dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\nvoid main() {\nvec3 color = texture2D(outputResultMap, v_uv).xyz;\nif (luminance(SRGBToLinear(color)) > texSize.z) {\ngl_FragColor = vec4(color, 1.0);\n} else {\ngl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n}\n}", }, { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nvarying vec2 v_uv;\nuniform mediump vec4 texSize;\nuniform sampler2D bloomTexture;\nvec3 downsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture2D(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main()\n{\nvec3 result = downsample4taps(v_uv, 1.0 / texSize.xy).rgb;\ngl_FragColor = vec4(result, 1.0);\n}", }, { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nvarying vec2 v_uv;\nuniform mediump vec4 texSize;\nuniform sampler2D bloomTexture;\nvec3 upsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture2D(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture2D(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main() {\nvec3 result = upsample4taps(v_uv, 0.5 / texSize.xy).rgb;\ngl_FragColor = vec4(result, 1.0);\n}", }, { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nvarying vec2 v_uv;\nuniform mediump vec4 texSize;\nuniform sampler2D outputResultMap;\nuniform sampler2D bloomTexture;\nvoid main() {\nvec4 hdrColor = texture2D(outputResultMap, v_uv);\nvec3 bloomColor = texture2D(bloomTexture, v_uv).rgb;\nvec3 result = hdrColor.rgb + bloomColor * texSize.w * hdrColor.a;\ngl_FragColor = vec4(result, hdrColor.a);\n}", } ], @@ -138,13 +138,13 @@ export const glsl1 = [ ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nuniform mediump vec4 cc_planarNDInfo;\nvarying float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nuniform highp mat4 cc_matView;\nuniform highp mat4 cc_matProj;\nuniform highp vec4 cc_cameraPos;\nuniform mediump vec4 cc_mainLitDir;\n#if !USE_INSTANCING\n#if USE_BATCHING\nuniform highp mat4 cc_matWorlds[10];\n#else\nuniform highp mat4 cc_matWorld;\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nuniform mediump vec4 cc_planarNDInfo;\nvarying float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nuniform lowp vec4 cc_shadowColor;\nvec4 CCFragOutput (vec4 color) {\nreturn color;\n}\nvarying float v_dist;\nvec4 frag () {\nif(v_dist < 0.0)\ndiscard;\nreturn CCFragOutput(cc_shadowColor);\n}\nvoid main() { gl_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nuniform highp vec4 cc_joints[90];\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nattribute vec3 a_position;\nattribute vec3 a_normal;\nattribute vec2 a_texCoord;\nattribute vec4 a_tangent;\n#if CC_USE_SKINNING\nattribute vec4 a_joints;\nattribute vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nattribute highp vec4 a_jointAnimInfo;\n#endif\nattribute vec4 a_matWorld0;\nattribute vec4 a_matWorld1;\nattribute vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nattribute vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nattribute vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nattribute float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nattribute float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nuniform vec4 cc_displacementWeights[15];\nuniform vec4 cc_displacementTextureInfo;\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 uv = getPixelCoordFromLocation(location, cc_displacementTextureInfo.xy);\nreturn texture2D(tex, uv);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture2D(tex, x)),\ndecode32(texture2D(tex, y)),\ndecode32(texture2D(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nuniform highp vec4 cc_jointTextureInfo;\nuniform highp vec4 cc_jointAnimInfo;\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nuniform highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture2D(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture2D(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture2D(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nuniform highp vec4 cc_cameraPos;\nvarying vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nuniform mediump vec4 cc_screenSize;\n#if ANTIALIAS_TYPE == 1\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\nvec2 v_rgbNW, vec2 v_rgbNE,\nvec2 v_rgbSW, vec2 v_rgbSE,\nvec2 v_rgbM) {\nvec4 color;\nmediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\nvec3 rgbNW = texture2D(tex, v_rgbNW).xyz;\nvec3 rgbNE = texture2D(tex, v_rgbNE).xyz;\nvec3 rgbSW = texture2D(tex, v_rgbSW).xyz;\nvec3 rgbSE = texture2D(tex, v_rgbSE).xyz;\nvec4 texColor = texture2D(tex, v_rgbM);\nvec3 rgbM = texColor.xyz;\nvec3 luma = vec3(0.299, 0.587, 0.114);\nfloat lumaNW = dot(rgbNW, luma);\nfloat lumaNE = dot(rgbNE, luma);\nfloat lumaSW = dot(rgbSW, luma);\nfloat lumaSE = dot(rgbSE, luma);\nfloat lumaM = dot(rgbM, luma);\nfloat lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\nfloat lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\nmediump vec2 dir;\ndir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\ndir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\nfloat dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n(0.25 * (1.0 / 8.0)), (1.0/ 128.0));\nfloat rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\ndir = min(vec2(8.0, 8.0),\nmax(vec2(-8.0, -8.0),\ndir * rcpDirMin)) * inverseVP;\nvec3 rgbA = 0.5 * (\ntexture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\ntexture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\nvec3 rgbB = rgbA * 0.5 + 0.25 * (\ntexture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz +\ntexture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz);\nfloat lumaB = dot(rgbB, luma);\nif ((lumaB < lumaMin) || (lumaB > lumaMax))\ncolor = vec4(rgbA, texColor.a);\nelse\ncolor = vec4(rgbB, texColor.a);\nreturn color;\n}\n#endif\nvarying vec2 v_uv;\nuniform sampler2D outputResultMap;\nvoid texcoords(vec2 fragCoord, vec2 resolution,\nout vec2 v_rgbNW, out vec2 v_rgbNE,\nout vec2 v_rgbSW, out vec2 v_rgbSE,\nout vec2 v_rgbM) {\nvec2 inverseVP = 1.0 / resolution.xy;\nv_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\nv_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\nv_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\nv_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\nv_rgbM = vec2(fragCoord * inverseVP);\n}\nvoid main () {\nmediump vec2 v_rgbNW;\nmediump vec2 v_rgbNE;\nmediump vec2 v_rgbSW;\nmediump vec2 v_rgbSE;\nmediump vec2 v_rgbM;\n#if ANTIALIAS_TYPE == 1\nvec2 resolution = cc_screenSize.xy;\nvec2 fragCoord = v_uv * resolution;\ntexcoords(fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\ngl_FragColor = fxaa(outputResultMap, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n#else\ngl_FragColor = texture2D(outputResultMap, v_uv);\n#endif\n}", } ], diff --git a/cocos/core/builtin/shader-sources/glsl3.ts b/cocos/core/builtin/shader-sources/glsl3.ts index 1403687dabb..2483225c77c 100644 --- a/cocos/core/builtin/shader-sources/glsl3.ts +++ b/cocos/core/builtin/shader-sources/glsl3.ts @@ -88,11 +88,11 @@ export const glsl3 = [ ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nout highp vec4 v_shadowPos;\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#elif !USE_BATCHING\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_shadowWHPBInfo.w, cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nin vec4 a_color;\nout lowp vec4 v_color;\n#endif\nout vec3 v_position;\nout mediump vec3 v_normal;\nout vec2 v_uv;\n#if HAS_SECOND_UV\nout mediump vec2 v_uv1;\n#endif\n#if CC_RECEIVE_SHADOW\nout mediump vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nout mediump vec4 v_tangent;\n#endif\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nin vec2 a_texCoord1;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nout vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_tangent.w = In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nout highp vec4 v_shadowPos;\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#elif !USE_BATCHING\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_shadowWHPBInfo.w, cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nin vec4 a_color;\nout lowp vec4 v_color;\n#endif\nout vec3 v_position;\nout mediump vec3 v_normal;\nout vec2 v_uv;\n#if HAS_SECOND_UV\nout mediump vec2 v_uv1;\n#endif\n#if CC_RECEIVE_SHADOW\nout mediump vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nout mediump vec4 v_tangent;\n#endif\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nin vec2 a_texCoord1;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nout vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_tangent.w = In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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 Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nin float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\nfloat GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\nfloat dist = length(viewPos);\nreturn (dist - near) / (far - near);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn GetLinearDepthFromViewSpace(viewStartPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n}\n#if CC_RECEIVE_SHADOW\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nfloat NativePCFShadowFactorHard (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\n#if CC_SHADOWMAP_FORMAT == 1\nreturn step(shadowNDCPos.z, dot(texture(shadowMap, shadowNDCPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nreturn step(shadowNDCPos.z, texture(shadowMap, shadowNDCPos.xy).x);\n#endif\n}\nfloat NativePCFShadowFactorSoft (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nvec2 shadowNDCPos_offset = shadowNDCPos.xy + oneTap;\nfloat block0, block1, block2, block3;\n#if CC_SHADOWMAP_FORMAT == 1\nblock0 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock0 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\nblock1 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)).x);\nblock2 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)).x);\nblock3 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)).x);\n#endif\nfloat coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nfloat shadowNDCPos_offset_L = shadowNDCPos.x - oneTap.x;\nfloat shadowNDCPos_offset_R = shadowNDCPos.x + oneTap.x;\nfloat shadowNDCPos_offset_U = shadowNDCPos.y - oneTap.y;\nfloat shadowNDCPos_offset_D = shadowNDCPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\n#if CC_SHADOWMAP_FORMAT == 1\nblock0 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock0 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)).x);\nblock1 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)).x);\nblock2 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)).x);\nblock3 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)).x);\nblock4 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\nblock5 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)).x);\nblock6 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)).x);\nblock7 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)).x);\nblock8 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)).x);\n#endif\nfloat coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\nfloat coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat NativePCFShadowFactorSoft5X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nvec2 twoTap = oneTap * 2.0;\nvec2 offset1 = shadowNDCPos.xy + vec2(-twoTap.x, -twoTap.y);\nvec2 offset2 = shadowNDCPos.xy + vec2(-oneTap.x, -twoTap.y);\nvec2 offset3 = shadowNDCPos.xy + vec2(0.0, -twoTap.y);\nvec2 offset4 = shadowNDCPos.xy + vec2(oneTap.x, -twoTap.y);\nvec2 offset5 = shadowNDCPos.xy + vec2(twoTap.x, -twoTap.y);\nvec2 offset6 = shadowNDCPos.xy + vec2(-twoTap.x, -oneTap.y);\nvec2 offset7 = shadowNDCPos.xy + vec2(-oneTap.x, -oneTap.y);\nvec2 offset8 = shadowNDCPos.xy + vec2(0.0, -oneTap.y);\nvec2 offset9 = shadowNDCPos.xy + vec2(oneTap.x, -oneTap.y);\nvec2 offset10 = shadowNDCPos.xy + vec2(twoTap.x, -oneTap.y);\nvec2 offset11 = shadowNDCPos.xy + vec2(-twoTap.x, 0.0);\nvec2 offset12 = shadowNDCPos.xy + vec2(-oneTap.x, 0.0);\nvec2 offset13 = shadowNDCPos.xy + vec2(0.0, 0.0);\nvec2 offset14 = shadowNDCPos.xy + vec2(oneTap.x, 0.0);\nvec2 offset15 = shadowNDCPos.xy + vec2(twoTap.x, 0.0);\nvec2 offset16 = shadowNDCPos.xy + vec2(-twoTap.x, oneTap.y);\nvec2 offset17 = shadowNDCPos.xy + vec2(-oneTap.x, oneTap.y);\nvec2 offset18 = shadowNDCPos.xy + vec2(0.0, oneTap.y);\nvec2 offset19 = shadowNDCPos.xy + vec2(oneTap.x, oneTap.y);\nvec2 offset20 = shadowNDCPos.xy + vec2(twoTap.x, oneTap.y);\nvec2 offset21 = shadowNDCPos.xy + vec2(-twoTap.x, twoTap.y);\nvec2 offset22 = shadowNDCPos.xy + vec2(-oneTap.x, twoTap.y);\nvec2 offset23 = shadowNDCPos.xy + vec2(0.0, twoTap.y);\nvec2 offset24 = shadowNDCPos.xy + vec2(oneTap.x, twoTap.y);\nvec2 offset25 = shadowNDCPos.xy + vec2(twoTap.x, twoTap.y);\nfloat block1, block2, block3, block4, block5, block6, block7, block8, block9, block10, block11, block12, block13, block14, block15, block16, block17, block18, block19, block20, block21, block22, block23, block24, block25;\n#if CC_SHADOWMAP_FORMAT == 1\nblock1 = step(shadowNDCPos.z, dot(texture(shadowMap, offset1), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture(shadowMap, offset2), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture(shadowMap, offset3), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(shadowNDCPos.z, dot(texture(shadowMap, offset4), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(shadowNDCPos.z, dot(texture(shadowMap, offset5), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(shadowNDCPos.z, dot(texture(shadowMap, offset6), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(shadowNDCPos.z, dot(texture(shadowMap, offset7), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(shadowNDCPos.z, dot(texture(shadowMap, offset8), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock9 = step(shadowNDCPos.z, dot(texture(shadowMap, offset9), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock10 = step(shadowNDCPos.z, dot(texture(shadowMap, offset10), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock11 = step(shadowNDCPos.z, dot(texture(shadowMap, offset11), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock12 = step(shadowNDCPos.z, dot(texture(shadowMap, offset12), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock13 = step(shadowNDCPos.z, dot(texture(shadowMap, offset13), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock14 = step(shadowNDCPos.z, dot(texture(shadowMap, offset14), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock15 = step(shadowNDCPos.z, dot(texture(shadowMap, offset15), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock16 = step(shadowNDCPos.z, dot(texture(shadowMap, offset16), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock17 = step(shadowNDCPos.z, dot(texture(shadowMap, offset17), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock18 = step(shadowNDCPos.z, dot(texture(shadowMap, offset18), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock19 = step(shadowNDCPos.z, dot(texture(shadowMap, offset19), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock20 = step(shadowNDCPos.z, dot(texture(shadowMap, offset20), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock21 = step(shadowNDCPos.z, dot(texture(shadowMap, offset21), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock22 = step(shadowNDCPos.z, dot(texture(shadowMap, offset22), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock23 = step(shadowNDCPos.z, dot(texture(shadowMap, offset23), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock24 = step(shadowNDCPos.z, dot(texture(shadowMap, offset24), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock25 = step(shadowNDCPos.z, dot(texture(shadowMap, offset25), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock1 = step(shadowNDCPos.z, texture(shadowMap, offset1).x);\nblock2 = step(shadowNDCPos.z, texture(shadowMap, offset2).x);\nblock3 = step(shadowNDCPos.z, texture(shadowMap, offset3).x);\nblock4 = step(shadowNDCPos.z, texture(shadowMap, offset4).x);\nblock5 = step(shadowNDCPos.z, texture(shadowMap, offset5).x);\nblock6 = step(shadowNDCPos.z, texture(shadowMap, offset6).x);\nblock7 = step(shadowNDCPos.z, texture(shadowMap, offset7).x);\nblock8 = step(shadowNDCPos.z, texture(shadowMap, offset8).x);\nblock9 = step(shadowNDCPos.z, texture(shadowMap, offset9).x);\nblock10 = step(shadowNDCPos.z, texture(shadowMap, offset10).x);\nblock11 = step(shadowNDCPos.z, texture(shadowMap, offset11).x);\nblock12 = step(shadowNDCPos.z, texture(shadowMap, offset12).x);\nblock13 = step(shadowNDCPos.z, texture(shadowMap, offset13).x);\nblock14 = step(shadowNDCPos.z, texture(shadowMap, offset14).x);\nblock15 = step(shadowNDCPos.z, texture(shadowMap, offset15).x);\nblock16 = step(shadowNDCPos.z, texture(shadowMap, offset16).x);\nblock17 = step(shadowNDCPos.z, texture(shadowMap, offset17).x);\nblock18 = step(shadowNDCPos.z, texture(shadowMap, offset18).x);\nblock19 = step(shadowNDCPos.z, texture(shadowMap, offset19).x);\nblock20 = step(shadowNDCPos.z, texture(shadowMap, offset20).x);\nblock21 = step(shadowNDCPos.z, texture(shadowMap, offset21).x);\nblock22 = step(shadowNDCPos.z, texture(shadowMap, offset22).x);\nblock23 = step(shadowNDCPos.z, texture(shadowMap, offset23).x);\nblock24 = step(shadowNDCPos.z, texture(shadowMap, offset24).x);\nblock25 = step(shadowNDCPos.z, texture(shadowMap, offset25).x);\n#endif\nvec2 coef = fract(shadowNDCPos.xy * shadowMapResolution);\nvec2 v1X1 = mix(vec2(block1, block6), vec2(block2, block7), coef.xx);\nvec2 v1X2 = mix(vec2(block2, block7), vec2(block3, block8), coef.xx);\nvec2 v1X3 = mix(vec2(block3, block8), vec2(block4, block9), coef.xx);\nvec2 v1X4 = mix(vec2(block4, block9), vec2(block5, block10), coef.xx);\nfloat v1 = mix(v1X1.x, v1X1.y, coef.y) + mix(v1X2.x, v1X2.y, coef.y) + mix(v1X3.x, v1X3.y, coef.y) + mix(v1X4.x, v1X4.y, coef.y);\nvec2 v2X1 = mix(vec2(block6, block11), vec2(block7, block12), coef.xx);\nvec2 v2X2 = mix(vec2(block7, block12), vec2(block8, block13), coef.xx);\nvec2 v2X3 = mix(vec2(block8, block13), vec2(block9, block14), coef.xx);\nvec2 v2X4 = mix(vec2(block9, block14), vec2(block10, block15), coef.xx);\nfloat v2 = mix(v2X1.x, v2X1.y, coef.y) + mix(v2X2.x, v2X2.y, coef.y) + mix(v2X3.x, v2X3.y, coef.y) + mix(v2X4.x, v2X4.y, coef.y);\nvec2 v3X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\nvec2 v3X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\nvec2 v3X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\nvec2 v3X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\nfloat v3 = mix(v3X1.x, v3X1.y, coef.y) + mix(v3X2.x, v3X2.y, coef.y) + mix(v3X3.x, v3X3.y, coef.y) + mix(v3X4.x, v3X4.y, coef.y);\nvec2 v4X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\nvec2 v4X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\nvec2 v4X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\nvec2 v4X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\nfloat v4 = mix(v4X1.x, v4X1.y, coef.y) + mix(v4X2.x, v4X2.y, coef.y) + mix(v4X3.x, v4X3.y, coef.y) + mix(v4X4.x, v4X4.y, coef.y);\nvec2 v5X1 = mix(vec2(block16, block21), vec2(block17, block22), coef.xx);\nvec2 v5X2 = mix(vec2(block17, block22), vec2(block18, block23), coef.xx);\nvec2 v5X3 = mix(vec2(block18, block23), vec2(block19, block24), coef.xx);\nvec2 v5X4 = mix(vec2(block19, block24), vec2(block20, block25), coef.xx);\nfloat v5 = mix(v5X1.x, v5X1.y, coef.y) + mix(v5X2.x, v5X2.y, coef.y) + mix(v5X3.x, v5X3.y, coef.y) + mix(v5X4.x, v5X4.y, coef.y);\nfloat fAvg = (v1 + v2 + v3 + v4 + v5) * 0.05;\nreturn fAvg;\n}\nbool GetShadowNDCPos(out vec3 shadowNDCPos, vec4 shadowPosWithDepthBias)\n{\nshadowNDCPos = shadowPosWithDepthBias.xyz / shadowPosWithDepthBias.w * 0.5 + 0.5;\nif (shadowNDCPos.x < 0.0 || shadowNDCPos.x > 1.0 ||\nshadowNDCPos.y < 0.0 || shadowNDCPos.y > 1.0 ||\nshadowNDCPos.z < 0.0 || shadowNDCPos.z > 1.0) {\nreturn false;\n}\nshadowNDCPos.xy = cc_cameraPos.w == 1.0 ? vec2(shadowNDCPos.xy.x, 1.0 - shadowNDCPos.xy.y) : shadowNDCPos.xy;\nreturn true;\n}\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, mat4 matLightView, vec2 projScaleXY)\n{\nvec4 newShadowPos = shadowPos;\nif (normalBias > EPSILON_LOWP)\n{\nvec4 viewNormal = matLightView * vec4(worldNormal, 0.0);\nif (viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > EPSILON) {\nclipSpacePos.z = GetLinearDepthFromViewSpace(viewSpacePos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias, float projScaleZ, float projBiasZ)\n{\nfloat coeffA = projScaleZ;\nfloat coeffB = projBiasZ;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetDirLightShadowFactorHard (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorHard(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft3X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft5X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorHard(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft3X(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft5X(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nvec4 pos = ApplyShadowDepthBias_Perspective(shadowPos, shadowBias.x);\nif (pcf > 2.9) {\nreturn CCGetSpotLightShadowFactorSoft5X(pos, worldPos);\n} else if (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft3X(pos, worldPos);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(pos, worldPos);\n}else {\nreturn CCGetSpotLightShadowFactorHard(pos, worldPos);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y, cc_matLightView, cc_shadowProjInfo.xy);\npos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 2.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n} else if (pcf > 1.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n}else {\nrealtimeShadow = CCGetDirLightShadowFactorHard(pos);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\nint CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out mat4 matShadowView, vec3 worldPos) {\nfor (int i = 0; i < 4; i++) {\nvec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\nvec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;\nif (clipPos.x < (0.0 + cc_csmInfo.y) || clipPos.x > (1.0 - cc_csmInfo.y) ||\nclipPos.y < (0.0 + cc_csmInfo.y) || clipPos.y > (1.0 - cc_csmInfo.y) ||\nclipPos.z < 0.0 || clipPos.z > 1.0) {\ncontinue;\n}\ncsmPos = cc_matCSMViewProjAtlas[i] * vec4(worldPos.xyz, 1.0);\nshadowProjDepthInfo = cc_csmProjDepthInfo[i];\nshadowProjInfo = cc_csmProjInfo[i];\nmatShadowView = cc_matCSMView[i];\nreturn i;\n}\nreturn -1;\n}\nfloat CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias)\n{\nvec4 csmPos = vec4(1.0);\nvec4 shadowProjDepthInfo, shadowProjInfo;\nmat4 matLightView;\nint level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, matLightView, worldPos);\nif (level < 0) { return 1.0; }\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(csmPos, N, shadowBias.y, matLightView, shadowProjInfo.xy);\npos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, shadowProjDepthInfo.x, shadowProjDepthInfo.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 2.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n} else if (pcf > 1.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n} else if (pcf > 0.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n}else {\nrealtimeShadow = CCGetDirLightShadowFactorHard(pos);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nuniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nuniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\nfloat specularIntensity;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.08 * s.specularIntensity), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nif (cc_shadowLPNNInfo.w > 0.0) {\nshadow = CCCSMFactorBase(position, N, s.shadowBias);\n} else {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > EPSILON_LOWP) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nin highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nin vec3 v_luv;\nuniform sampler2D cc_lightingMap;\n#endif\nin vec3 v_position;\nin vec2 v_uv;\n#if HAS_SECOND_UV\nin mediump vec2 v_uv1;\n#endif\nin mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nin mediump vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nin lowp vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nin mediump vec4 v_tangent;\nuniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nuniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nuniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nuniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nuniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(cc_lightingMap, v_luv.xy);\ns.lightmap = lightColor.xyz * v_luv.z;\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5);\nvec3 bitangent = cross(v_normal, v_tangent.xyz) * v_tangent.w;\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent.xyz) +\n(nmmp.y * emissiveScaleParam.w) * normalize(bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.specularIntensity = 0.5;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\n#if CC_PIPELINE_TYPE == 0\n#define LIGHTS_PER_PASS 1\n#else\n#define LIGHTS_PER_PASS 10\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nlayout(std140) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(std430, binding = 4) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(std430, binding = 5) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(std430, binding = 6) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor2 = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nin vec2 a_texCoord1;\n#endif\nout vec2 v_uv;\n#if HAS_SECOND_UV\nout vec2 v_uv1;\n#endif\nout vec4 v_worldPos;\nout float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nin vec2 a_texCoord1;\n#endif\nout vec2 v_uv;\n#if HAS_SECOND_UV\nout vec2 v_uv1;\n#endif\nout vec4 v_worldPos;\nout float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nlayout(std140) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nfloat GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\nfloat dist = length(viewPos);\nreturn (dist - near) / (far - near);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn GetLinearDepthFromViewSpace(viewStartPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n}\n#if CC_RECEIVE_SHADOW\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nuniform highp sampler2D cc_shadowMap;\nuniform highp sampler2D cc_spotLightingMap;\n#endif\nin vec2 v_uv;\n#if HAS_SECOND_UV\nin vec2 v_uv1;\n#endif\nin vec4 v_worldPos;\nin float v_clip_depth;\n#if USE_ALBEDO_MAP\nuniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], @@ -108,25 +108,25 @@ export const glsl3 = [ ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nin lowp vec4 a_color;\nout lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nout vec2 v_uv;\nlayout(std140) uniform TexCoords {\nvec4 tilingOffset;\n};\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nout float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nin lowp vec4 a_color;\nout lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nout vec2 v_uv;\nlayout(std140) uniform TexCoords {\nvec4 tilingOffset;\n};\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nin float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#if USE_ALPHA_TEST\n#endif\n#if USE_TEXTURE\nin vec2 v_uv;\nuniform sampler2D mainTexture;\n#endif\nlayout(std140) uniform Constant {\nvec4 mainColor;\nvec4 colorScaleAndCutoff;\n};\n#if USE_VERTEX_COLOR\nin lowp vec4 v_color;\n#endif\nvec4 frag () {\nvec4 o = mainColor;\no.rgb *= colorScaleAndCutoff.xyz;\n#if USE_VERTEX_COLOR\no.rgb *= SRGBToLinear(v_color.rgb);\no.a *= v_color.a;\n#endif\n#if USE_TEXTURE\nvec4 texColor = texture(mainTexture, v_uv);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\no *= texColor;\n#endif\n#if USE_ALPHA_TEST\nif (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;\n#endif\nCC_APPLY_FOG(o);\nreturn CCFragOutput(o);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nin vec2 v_uv;\nlayout(std140) uniform BloomUBO {\nmediump vec4 texSize;\n};\nuniform sampler2D outputResultMap;\nlayout(location = 0) out vec4 fragColor;\nfloat luminance(vec3 color) {\nreturn dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\nvoid main() {\nvec3 color = texture(outputResultMap, v_uv).xyz;\nif (luminance(SRGBToLinear(color)) > texSize.z) {\nfragColor = vec4(color, 1.0);\n} else {\nfragColor = vec4(0.0, 0.0, 0.0, 1.0);\n}\n}", }, { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nin vec2 v_uv;\nlayout(std140) uniform BloomUBO {\nmediump vec4 texSize;\n};\nuniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvec3 downsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main()\n{\nvec3 result = downsample4taps(v_uv, 1.0 / texSize.xy).rgb;\nfragColor = vec4(result, 1.0);\n}", }, { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nin vec2 v_uv;\nlayout(std140) uniform BloomUBO {\nmediump vec4 texSize;\n};\nuniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvec3 upsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main() {\nvec3 result = upsample4taps(v_uv, 0.5 / texSize.xy).rgb;\nfragColor = vec4(result, 1.0);\n}", }, { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nin vec2 v_uv;\nlayout(std140) uniform BloomUBO {\nmediump vec4 texSize;\n};\nuniform sampler2D outputResultMap;\nuniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvoid main() {\nvec4 hdrColor = texture(outputResultMap, v_uv);\nvec3 bloomColor = texture(bloomTexture, v_uv).rgb;\nvec3 result = hdrColor.rgb + bloomColor * texSize.w * hdrColor.a;\nfragColor = vec4(result, hdrColor.a);\n}", } ], @@ -138,13 +138,13 @@ export const glsl3 = [ ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\nout float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(std140) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(std140) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\nout float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nlayout(std140) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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 float v_dist;\nvec4 frag () {\nif(v_dist < 0.0)\ndiscard;\nreturn CCFragOutput(cc_shadowColor);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nin vec3 a_position;\nin vec3 a_normal;\nin vec2 a_texCoord;\nin vec4 a_tangent;\n#if CC_USE_SKINNING\nin vec4 a_joints;\nin vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nin highp vec4 a_jointAnimInfo;\n#endif\nin vec4 a_matWorld0;\nin vec4 a_matWorld1;\nin vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nin vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nin vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nin float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nin float a_vertexId;\nint getVertexId() {\nreturn int(a_vertexId);\n}\n#endif\n#if CC_USE_MORPH\nlayout(std140) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nuniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nuniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nuniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(std140) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(std140) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nuniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nuniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(std140) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nout vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(std140) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if ANTIALIAS_TYPE == 1\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\nvec2 v_rgbNW, vec2 v_rgbNE,\nvec2 v_rgbSW, vec2 v_rgbSE,\nvec2 v_rgbM) {\nvec4 color;\nmediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\nvec3 rgbNW = texture(tex, v_rgbNW).xyz;\nvec3 rgbNE = texture(tex, v_rgbNE).xyz;\nvec3 rgbSW = texture(tex, v_rgbSW).xyz;\nvec3 rgbSE = texture(tex, v_rgbSE).xyz;\nvec4 texColor = texture(tex, v_rgbM);\nvec3 rgbM = texColor.xyz;\nvec3 luma = vec3(0.299, 0.587, 0.114);\nfloat lumaNW = dot(rgbNW, luma);\nfloat lumaNE = dot(rgbNE, luma);\nfloat lumaSW = dot(rgbSW, luma);\nfloat lumaSE = dot(rgbSE, luma);\nfloat lumaM = dot(rgbM, luma);\nfloat lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\nfloat lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\nmediump vec2 dir;\ndir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\ndir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\nfloat dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n(0.25 * (1.0 / 8.0)), (1.0/ 128.0));\nfloat rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\ndir = min(vec2(8.0, 8.0),\nmax(vec2(-8.0, -8.0),\ndir * rcpDirMin)) * inverseVP;\nvec3 rgbA = 0.5 * (\ntexture(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\ntexture(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\nvec3 rgbB = rgbA * 0.5 + 0.25 * (\ntexture(tex, fragCoord * inverseVP + dir * -0.5).xyz +\ntexture(tex, fragCoord * inverseVP + dir * 0.5).xyz);\nfloat lumaB = dot(rgbB, luma);\nif ((lumaB < lumaMin) || (lumaB > lumaMax))\ncolor = vec4(rgbA, texColor.a);\nelse\ncolor = vec4(rgbB, texColor.a);\nreturn color;\n}\n#endif\nin vec2 v_uv;\nuniform sampler2D outputResultMap;\nlayout(location = 0) out vec4 fragColor;\nvoid texcoords(vec2 fragCoord, vec2 resolution,\nout vec2 v_rgbNW, out vec2 v_rgbNE,\nout vec2 v_rgbSW, out vec2 v_rgbSE,\nout vec2 v_rgbM) {\nvec2 inverseVP = 1.0 / resolution.xy;\nv_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\nv_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\nv_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\nv_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\nv_rgbM = vec2(fragCoord * inverseVP);\n}\nvoid main () {\nmediump vec2 v_rgbNW;\nmediump vec2 v_rgbNE;\nmediump vec2 v_rgbSW;\nmediump vec2 v_rgbSE;\nmediump vec2 v_rgbM;\n#if ANTIALIAS_TYPE == 1\nvec2 resolution = cc_screenSize.xy;\nvec2 fragCoord = v_uv * resolution;\ntexcoords(fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\nfragColor = fxaa(outputResultMap, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n#else\nfragColor = texture(outputResultMap, v_uv);\n#endif\n}", } ], diff --git a/cocos/core/builtin/shader-sources/glsl4.ts b/cocos/core/builtin/shader-sources/glsl4.ts index 4437495005c..05ab3b35bb2 100644 --- a/cocos/core/builtin/shader-sources/glsl4.ts +++ b/cocos/core/builtin/shader-sources/glsl4.ts @@ -88,11 +88,11 @@ export const glsl4 = [ ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nlayout(location = 1) out highp vec4 v_shadowPos;\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#elif !USE_BATCHING\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_shadowWHPBInfo.w, cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nlayout(location = 14) in vec4 a_color;\nlayout(location = 2) out lowp vec4 v_color;\n#endif\nlayout(location = 3) out vec3 v_position;\nlayout(location = 4) out mediump vec3 v_normal;\nlayout(location = 5) out vec2 v_uv;\n#if HAS_SECOND_UV\nlayout(location = 6) out mediump vec2 v_uv1;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 7) out mediump vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nlayout(location = 8) out mediump vec4 v_tangent;\n#endif\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nlayout(location = 15) in vec2 a_texCoord1;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 9) out vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_tangent.w = In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\nlayout(location = 1) out highp vec4 v_shadowPos;\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\n#if CC_RECEIVE_SHADOW\nvec2 CCGetShadowBias()\n{\n#if USE_INSTANCING\nreturn vec2(a_localShadowBias.x + cc_shadowWHPBInfo.w, a_localShadowBias.y + cc_shadowLPNNInfo.z);\n#elif !USE_BATCHING\nreturn vec2(cc_localShadowBias.x + cc_shadowWHPBInfo.w, cc_localShadowBias.y + cc_shadowLPNNInfo.z);\n#else\nreturn vec2(cc_shadowWHPBInfo.w, cc_shadowLPNNInfo.z);\n#endif\n}\n#endif\n#if USE_VERTEX_COLOR\nlayout(location = 14) in vec4 a_color;\nlayout(location = 2) out lowp vec4 v_color;\n#endif\nlayout(location = 3) out vec3 v_position;\nlayout(location = 4) out mediump vec3 v_normal;\nlayout(location = 5) out vec2 v_uv;\n#if HAS_SECOND_UV\nlayout(location = 6) out mediump vec2 v_uv1;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 7) out mediump vec2 v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nlayout(location = 8) out mediump vec4 v_tangent;\n#endif\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nlayout(location = 15) in vec2 a_texCoord1;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 9) out vec3 v_luv;\nvoid CCLightingMapCaclUV()\n{\n#if !USE_INSTANCING\nv_luv.xy = cc_lightingMapUVParam.xy + a_texCoord1 * cc_lightingMapUVParam.z;\nv_luv.z = cc_lightingMapUVParam.w;\n#else\nv_luv.xy = a_lightingMapUVParam.xy + a_texCoord1 * a_lightingMapUVParam.z;\nv_luv.z = a_lightingMapUVParam.w;\n#endif\n}\n#endif\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nvec4 pos = matWorld * In.position;\nv_position = pos.xyz;\nv_normal = normalize((matWorldIT * vec4(In.normal, 0.0)).xyz);\n#if CC_RECEIVE_SHADOW\nv_shadowBias = CCGetShadowBias();\n#endif\n#if USE_TWOSIDE\nvec3 viewDirect = normalize(cc_cameraPos.xyz - v_position);\nv_normal *= dot(v_normal, viewDirect) < 0.0 ? -1.0 : 1.0;\n#endif\n#if USE_NORMAL_MAP\nv_tangent.xyz = normalize((matWorld * vec4(In.tangent.xyz, 0.0)).xyz);\nv_tangent.w = In.tangent.w;\n#endif\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv1 = cc_cameraPos.w > 1.0 ? vec2(v_uv1.x, 1.0 - v_uv1.y) : v_uv1;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(pos);\nv_shadowPos = cc_matLightViewProj * pos;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nCCLightingMapCaclUV();\n#endif\ngl_Position = cc_matProj * (cc_matView * matWorld) * In.position;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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 = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) in float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\nfloat GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\nfloat dist = length(viewPos);\nreturn (dist - near) / (far - near);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn GetLinearDepthFromViewSpace(viewStartPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\nhighp float unpackHighpData (float mainPart, float modPart) {\nhighp float data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp float unpackHighpData (float mainPart, float modPart, const float modValue) {\nhighp float data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out float mainPart, out float modPart, highp float data, const float modValue) {\nhighp float divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart) {\nhighp vec2 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec2 unpackHighpData (vec2 mainPart, vec2 modPart, const float modValue) {\nhighp vec2 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec2 mainPart, out vec2 modPart, highp vec2 data, const float modValue) {\nhighp vec2 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart) {\nhighp vec3 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec3 unpackHighpData (vec3 mainPart, vec3 modPart, const float modValue) {\nhighp vec3 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec3 mainPart, out vec3 modPart, highp vec3 data, const float modValue) {\nhighp vec3 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart) {\nhighp vec4 data = mainPart;\nreturn data + modPart;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data) {\nmainPart = fract(data);\nmodPart = data - mainPart;\n}\nhighp vec4 unpackHighpData (vec4 mainPart, vec4 modPart, const float modValue) {\nhighp vec4 data = mainPart * modValue;\nreturn data + modPart * modValue;\n}\nvoid packHighpData (out vec4 mainPart, out vec4 modPart, highp vec4 data, const float modValue) {\nhighp vec4 divide = data / modValue;\nmainPart = floor(divide);\nmodPart = (data - mainPart * modValue) / modValue;\n}\nfloat NativePCFShadowFactorHard (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\n#if CC_SHADOWMAP_FORMAT == 1\nreturn step(shadowNDCPos.z, dot(texture(shadowMap, shadowNDCPos.xy), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nreturn step(shadowNDCPos.z, texture(shadowMap, shadowNDCPos.xy).x);\n#endif\n}\nfloat NativePCFShadowFactorSoft (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nvec2 shadowNDCPos_offset = shadowNDCPos.xy + oneTap;\nfloat block0, block1, block2, block3;\n#if CC_SHADOWMAP_FORMAT == 1\nblock0 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock0 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\nblock1 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos.y)).x);\nblock2 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset.y)).x);\nblock3 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset.x, shadowNDCPos_offset.y)).x);\n#endif\nfloat coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block2, block3, coefX);\nfloat coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\nreturn mix(resultX, resultY, coefY);\n}\nfloat NativePCFShadowFactorSoft3X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nfloat shadowNDCPos_offset_L = shadowNDCPos.x - oneTap.x;\nfloat shadowNDCPos_offset_R = shadowNDCPos.x + oneTap.x;\nfloat shadowNDCPos_offset_U = shadowNDCPos.y - oneTap.y;\nfloat shadowNDCPos_offset_D = shadowNDCPos.y + oneTap.y;\nfloat block0, block1, block2, block3, block4, block5, block6, block7, block8;\n#if CC_SHADOWMAP_FORMAT == 1\nblock0 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock1 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(shadowNDCPos.z, dot(texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock0 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_U)).x);\nblock1 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_U)).x);\nblock2 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_U)).x);\nblock3 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos.y)).x);\nblock4 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos.y)).x);\nblock5 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos.y)).x);\nblock6 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_L, shadowNDCPos_offset_D)).x);\nblock7 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos.x, shadowNDCPos_offset_D)).x);\nblock8 = step(shadowNDCPos.z, texture(shadowMap, vec2(shadowNDCPos_offset_R, shadowNDCPos_offset_D)).x);\n#endif\nfloat coefX = mod(shadowNDCPos.x, oneTap.x) * shadowMapResolution.x;\nfloat coefY = mod(shadowNDCPos.y, oneTap.y) * shadowMapResolution.y;\nfloat shadow = 0.0;\nfloat resultX = mix(block0, block1, coefX);\nfloat resultY = mix(block3, block4, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block1, block2, coefX);\nresultY = mix(block4, block5, coefX);\nshadow += mix(resultX , resultY, coefY);\nresultX = mix(block3, block4, coefX);\nresultY = mix(block6, block7, coefX);\nshadow += mix(resultX, resultY, coefY);\nresultX = mix(block4, block5, coefX);\nresultY = mix(block7, block8, coefX);\nshadow += mix(resultX, resultY, coefY);\nreturn shadow * 0.25;\n}\nfloat NativePCFShadowFactorSoft5X (vec3 shadowNDCPos, sampler2D shadowMap, vec2 shadowMapResolution)\n{\nvec2 oneTap = 1.0 / shadowMapResolution;\nvec2 twoTap = oneTap * 2.0;\nvec2 offset1 = shadowNDCPos.xy + vec2(-twoTap.x, -twoTap.y);\nvec2 offset2 = shadowNDCPos.xy + vec2(-oneTap.x, -twoTap.y);\nvec2 offset3 = shadowNDCPos.xy + vec2(0.0, -twoTap.y);\nvec2 offset4 = shadowNDCPos.xy + vec2(oneTap.x, -twoTap.y);\nvec2 offset5 = shadowNDCPos.xy + vec2(twoTap.x, -twoTap.y);\nvec2 offset6 = shadowNDCPos.xy + vec2(-twoTap.x, -oneTap.y);\nvec2 offset7 = shadowNDCPos.xy + vec2(-oneTap.x, -oneTap.y);\nvec2 offset8 = shadowNDCPos.xy + vec2(0.0, -oneTap.y);\nvec2 offset9 = shadowNDCPos.xy + vec2(oneTap.x, -oneTap.y);\nvec2 offset10 = shadowNDCPos.xy + vec2(twoTap.x, -oneTap.y);\nvec2 offset11 = shadowNDCPos.xy + vec2(-twoTap.x, 0.0);\nvec2 offset12 = shadowNDCPos.xy + vec2(-oneTap.x, 0.0);\nvec2 offset13 = shadowNDCPos.xy + vec2(0.0, 0.0);\nvec2 offset14 = shadowNDCPos.xy + vec2(oneTap.x, 0.0);\nvec2 offset15 = shadowNDCPos.xy + vec2(twoTap.x, 0.0);\nvec2 offset16 = shadowNDCPos.xy + vec2(-twoTap.x, oneTap.y);\nvec2 offset17 = shadowNDCPos.xy + vec2(-oneTap.x, oneTap.y);\nvec2 offset18 = shadowNDCPos.xy + vec2(0.0, oneTap.y);\nvec2 offset19 = shadowNDCPos.xy + vec2(oneTap.x, oneTap.y);\nvec2 offset20 = shadowNDCPos.xy + vec2(twoTap.x, oneTap.y);\nvec2 offset21 = shadowNDCPos.xy + vec2(-twoTap.x, twoTap.y);\nvec2 offset22 = shadowNDCPos.xy + vec2(-oneTap.x, twoTap.y);\nvec2 offset23 = shadowNDCPos.xy + vec2(0.0, twoTap.y);\nvec2 offset24 = shadowNDCPos.xy + vec2(oneTap.x, twoTap.y);\nvec2 offset25 = shadowNDCPos.xy + vec2(twoTap.x, twoTap.y);\nfloat block1, block2, block3, block4, block5, block6, block7, block8, block9, block10, block11, block12, block13, block14, block15, block16, block17, block18, block19, block20, block21, block22, block23, block24, block25;\n#if CC_SHADOWMAP_FORMAT == 1\nblock1 = step(shadowNDCPos.z, dot(texture(shadowMap, offset1), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock2 = step(shadowNDCPos.z, dot(texture(shadowMap, offset2), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock3 = step(shadowNDCPos.z, dot(texture(shadowMap, offset3), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock4 = step(shadowNDCPos.z, dot(texture(shadowMap, offset4), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock5 = step(shadowNDCPos.z, dot(texture(shadowMap, offset5), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock6 = step(shadowNDCPos.z, dot(texture(shadowMap, offset6), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock7 = step(shadowNDCPos.z, dot(texture(shadowMap, offset7), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock8 = step(shadowNDCPos.z, dot(texture(shadowMap, offset8), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock9 = step(shadowNDCPos.z, dot(texture(shadowMap, offset9), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock10 = step(shadowNDCPos.z, dot(texture(shadowMap, offset10), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock11 = step(shadowNDCPos.z, dot(texture(shadowMap, offset11), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock12 = step(shadowNDCPos.z, dot(texture(shadowMap, offset12), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock13 = step(shadowNDCPos.z, dot(texture(shadowMap, offset13), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock14 = step(shadowNDCPos.z, dot(texture(shadowMap, offset14), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock15 = step(shadowNDCPos.z, dot(texture(shadowMap, offset15), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock16 = step(shadowNDCPos.z, dot(texture(shadowMap, offset16), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock17 = step(shadowNDCPos.z, dot(texture(shadowMap, offset17), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock18 = step(shadowNDCPos.z, dot(texture(shadowMap, offset18), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock19 = step(shadowNDCPos.z, dot(texture(shadowMap, offset19), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock20 = step(shadowNDCPos.z, dot(texture(shadowMap, offset20), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock21 = step(shadowNDCPos.z, dot(texture(shadowMap, offset21), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock22 = step(shadowNDCPos.z, dot(texture(shadowMap, offset22), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock23 = step(shadowNDCPos.z, dot(texture(shadowMap, offset23), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock24 = step(shadowNDCPos.z, dot(texture(shadowMap, offset24), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\nblock25 = step(shadowNDCPos.z, dot(texture(shadowMap, offset25), vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0)));\n#else\nblock1 = step(shadowNDCPos.z, texture(shadowMap, offset1).x);\nblock2 = step(shadowNDCPos.z, texture(shadowMap, offset2).x);\nblock3 = step(shadowNDCPos.z, texture(shadowMap, offset3).x);\nblock4 = step(shadowNDCPos.z, texture(shadowMap, offset4).x);\nblock5 = step(shadowNDCPos.z, texture(shadowMap, offset5).x);\nblock6 = step(shadowNDCPos.z, texture(shadowMap, offset6).x);\nblock7 = step(shadowNDCPos.z, texture(shadowMap, offset7).x);\nblock8 = step(shadowNDCPos.z, texture(shadowMap, offset8).x);\nblock9 = step(shadowNDCPos.z, texture(shadowMap, offset9).x);\nblock10 = step(shadowNDCPos.z, texture(shadowMap, offset10).x);\nblock11 = step(shadowNDCPos.z, texture(shadowMap, offset11).x);\nblock12 = step(shadowNDCPos.z, texture(shadowMap, offset12).x);\nblock13 = step(shadowNDCPos.z, texture(shadowMap, offset13).x);\nblock14 = step(shadowNDCPos.z, texture(shadowMap, offset14).x);\nblock15 = step(shadowNDCPos.z, texture(shadowMap, offset15).x);\nblock16 = step(shadowNDCPos.z, texture(shadowMap, offset16).x);\nblock17 = step(shadowNDCPos.z, texture(shadowMap, offset17).x);\nblock18 = step(shadowNDCPos.z, texture(shadowMap, offset18).x);\nblock19 = step(shadowNDCPos.z, texture(shadowMap, offset19).x);\nblock20 = step(shadowNDCPos.z, texture(shadowMap, offset20).x);\nblock21 = step(shadowNDCPos.z, texture(shadowMap, offset21).x);\nblock22 = step(shadowNDCPos.z, texture(shadowMap, offset22).x);\nblock23 = step(shadowNDCPos.z, texture(shadowMap, offset23).x);\nblock24 = step(shadowNDCPos.z, texture(shadowMap, offset24).x);\nblock25 = step(shadowNDCPos.z, texture(shadowMap, offset25).x);\n#endif\nvec2 coef = fract(shadowNDCPos.xy * shadowMapResolution);\nvec2 v1X1 = mix(vec2(block1, block6), vec2(block2, block7), coef.xx);\nvec2 v1X2 = mix(vec2(block2, block7), vec2(block3, block8), coef.xx);\nvec2 v1X3 = mix(vec2(block3, block8), vec2(block4, block9), coef.xx);\nvec2 v1X4 = mix(vec2(block4, block9), vec2(block5, block10), coef.xx);\nfloat v1 = mix(v1X1.x, v1X1.y, coef.y) + mix(v1X2.x, v1X2.y, coef.y) + mix(v1X3.x, v1X3.y, coef.y) + mix(v1X4.x, v1X4.y, coef.y);\nvec2 v2X1 = mix(vec2(block6, block11), vec2(block7, block12), coef.xx);\nvec2 v2X2 = mix(vec2(block7, block12), vec2(block8, block13), coef.xx);\nvec2 v2X3 = mix(vec2(block8, block13), vec2(block9, block14), coef.xx);\nvec2 v2X4 = mix(vec2(block9, block14), vec2(block10, block15), coef.xx);\nfloat v2 = mix(v2X1.x, v2X1.y, coef.y) + mix(v2X2.x, v2X2.y, coef.y) + mix(v2X3.x, v2X3.y, coef.y) + mix(v2X4.x, v2X4.y, coef.y);\nvec2 v3X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\nvec2 v3X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\nvec2 v3X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\nvec2 v3X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\nfloat v3 = mix(v3X1.x, v3X1.y, coef.y) + mix(v3X2.x, v3X2.y, coef.y) + mix(v3X3.x, v3X3.y, coef.y) + mix(v3X4.x, v3X4.y, coef.y);\nvec2 v4X1 = mix(vec2(block11, block16), vec2(block12, block17), coef.xx);\nvec2 v4X2 = mix(vec2(block12, block17), vec2(block13, block18), coef.xx);\nvec2 v4X3 = mix(vec2(block13, block18), vec2(block14, block19), coef.xx);\nvec2 v4X4 = mix(vec2(block14, block19), vec2(block15, block20), coef.xx);\nfloat v4 = mix(v4X1.x, v4X1.y, coef.y) + mix(v4X2.x, v4X2.y, coef.y) + mix(v4X3.x, v4X3.y, coef.y) + mix(v4X4.x, v4X4.y, coef.y);\nvec2 v5X1 = mix(vec2(block16, block21), vec2(block17, block22), coef.xx);\nvec2 v5X2 = mix(vec2(block17, block22), vec2(block18, block23), coef.xx);\nvec2 v5X3 = mix(vec2(block18, block23), vec2(block19, block24), coef.xx);\nvec2 v5X4 = mix(vec2(block19, block24), vec2(block20, block25), coef.xx);\nfloat v5 = mix(v5X1.x, v5X1.y, coef.y) + mix(v5X2.x, v5X2.y, coef.y) + mix(v5X3.x, v5X3.y, coef.y) + mix(v5X4.x, v5X4.y, coef.y);\nfloat fAvg = (v1 + v2 + v3 + v4 + v5) * 0.05;\nreturn fAvg;\n}\nbool GetShadowNDCPos(out vec3 shadowNDCPos, vec4 shadowPosWithDepthBias)\n{\nshadowNDCPos = shadowPosWithDepthBias.xyz / shadowPosWithDepthBias.w * 0.5 + 0.5;\nif (shadowNDCPos.x < 0.0 || shadowNDCPos.x > 1.0 ||\nshadowNDCPos.y < 0.0 || shadowNDCPos.y > 1.0 ||\nshadowNDCPos.z < 0.0 || shadowNDCPos.z > 1.0) {\nreturn false;\n}\nshadowNDCPos.xy = cc_cameraPos.w == 1.0 ? vec2(shadowNDCPos.xy.x, 1.0 - shadowNDCPos.xy.y) : shadowNDCPos.xy;\nreturn true;\n}\nvec4 ApplyShadowDepthBias_FaceNormal(vec4 shadowPos, vec3 worldNormal, float normalBias, mat4 matLightView, vec2 projScaleXY)\n{\nvec4 newShadowPos = shadowPos;\nif (normalBias > EPSILON_LOWP)\n{\nvec4 viewNormal = matLightView * vec4(worldNormal, 0.0);\nif (viewNormal.z < 0.1)\nnewShadowPos.xy += viewNormal.xy * projScaleXY * normalBias * clamp(viewNormal.z, 0.001, 0.1);\n}\nreturn newShadowPos;\n}\nvec4 ApplyShadowDepthBias_Perspective(vec4 shadowPos, float viewspaceDepthBias)\n{\nvec3 viewSpacePos;\nviewSpacePos.xy = shadowPos.xy * cc_shadowProjInfo.zw;\nviewSpacePos.z = shadowPos.z * cc_shadowInvProjDepthInfo.x + shadowPos.w * cc_shadowInvProjDepthInfo.y;\nviewSpacePos.xyz += cc_shadowProjDepthInfo.z * normalize(viewSpacePos.xyz) * viewspaceDepthBias;\nvec4 clipSpacePos;\nclipSpacePos.xy = viewSpacePos.xy * cc_shadowProjInfo.xy;\nclipSpacePos.zw = viewSpacePos.z * cc_shadowProjDepthInfo.xz + vec2(cc_shadowProjDepthInfo.y, 0.0);\nif (cc_shadowNFLSInfo.z > EPSILON) {\nclipSpacePos.z = GetLinearDepthFromViewSpace(viewSpacePos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\nclipSpacePos.z = (clipSpacePos.z * 2.0 - 1.0) * clipSpacePos.w;\n}\nreturn clipSpacePos;\n}\nvec4 ApplyShadowDepthBias_Orthographic(vec4 shadowPos, float viewspaceDepthBias, float projScaleZ, float projBiasZ)\n{\nfloat coeffA = projScaleZ;\nfloat coeffB = projBiasZ;\nfloat viewSpacePos_z = (shadowPos.z - coeffB) / coeffA;\nviewSpacePos_z += viewspaceDepthBias;\nvec4 result = shadowPos;\nresult.z = viewSpacePos_z * coeffA + coeffB;\nreturn result;\n}\nfloat CCGetDirLightShadowFactorHard (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorHard(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft3X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetDirLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nreturn NativePCFShadowFactorSoft5X(shadowNDCPos, cc_shadowMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorHard (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorHard(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft3X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft3X(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCGetSpotLightShadowFactorSoft5X (vec4 shadowPosWithDepthBias, vec3 worldPos) {\nvec3 shadowNDCPos;\nif (!GetShadowNDCPos(shadowNDCPos, shadowPosWithDepthBias)) {\nreturn 1.0;\n}\nif (cc_shadowNFLSInfo.z > EPSILON) {\nshadowNDCPos.z = CCGetLinearDepth(worldPos);\n}\nreturn NativePCFShadowFactorSoft5X(shadowNDCPos, cc_spotLightingMap, cc_shadowWHPBInfo.xy);\n}\nfloat CCSpotShadowFactorBase(vec4 shadowPos, vec3 worldPos, vec2 shadowBias)\n{\nfloat pcf = cc_shadowWHPBInfo.z;\nvec4 pos = ApplyShadowDepthBias_Perspective(shadowPos, shadowBias.x);\nif (pcf > 2.9) {\nreturn CCGetSpotLightShadowFactorSoft5X(pos, worldPos);\n} else if (pcf > 1.9) {\nreturn CCGetSpotLightShadowFactorSoft3X(pos, worldPos);\n}else if (pcf > 0.9) {\nreturn CCGetSpotLightShadowFactorSoft(pos, worldPos);\n}else {\nreturn CCGetSpotLightShadowFactorHard(pos, worldPos);\n}\n}\nfloat CCShadowFactorBase(vec4 shadowPos, vec3 N, vec2 shadowBias)\n{\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(shadowPos, N, shadowBias.y, cc_matLightView, cc_shadowProjInfo.xy);\npos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, cc_shadowProjDepthInfo.x, cc_shadowProjDepthInfo.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 2.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n} else if (pcf > 1.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n}else if (pcf > 0.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n}else {\nrealtimeShadow = CCGetDirLightShadowFactorHard(pos);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\nint CCGetCSMLevel(out vec4 csmPos, out vec4 shadowProjDepthInfo, out vec4 shadowProjInfo, out mat4 matShadowView, vec3 worldPos) {\nfor (int i = 0; i < 4; i++) {\nvec4 shadowPos = cc_matCSMViewProj[i] * vec4(worldPos.xyz, 1.0);\nvec3 clipPos = shadowPos.xyz / shadowPos.w * 0.5 + 0.5;\nif (clipPos.x < (0.0 + cc_csmInfo.y) || clipPos.x > (1.0 - cc_csmInfo.y) ||\nclipPos.y < (0.0 + cc_csmInfo.y) || clipPos.y > (1.0 - cc_csmInfo.y) ||\nclipPos.z < 0.0 || clipPos.z > 1.0) {\ncontinue;\n}\ncsmPos = cc_matCSMViewProjAtlas[i] * vec4(worldPos.xyz, 1.0);\nshadowProjDepthInfo = cc_csmProjDepthInfo[i];\nshadowProjInfo = cc_csmProjInfo[i];\nmatShadowView = cc_matCSMView[i];\nreturn i;\n}\nreturn -1;\n}\nfloat CCCSMFactorBase(vec3 worldPos, vec3 N, vec2 shadowBias)\n{\nvec4 csmPos = vec4(1.0);\nvec4 shadowProjDepthInfo, shadowProjInfo;\nmat4 matLightView;\nint level = CCGetCSMLevel(csmPos, shadowProjDepthInfo, shadowProjInfo, matLightView, worldPos);\nif (level < 0) { return 1.0; }\nfloat realtimeShadow = 1.0;\nvec4 pos = ApplyShadowDepthBias_FaceNormal(csmPos, N, shadowBias.y, matLightView, shadowProjInfo.xy);\npos = ApplyShadowDepthBias_Orthographic(pos, shadowBias.x, shadowProjDepthInfo.x, shadowProjDepthInfo.y);\nfloat pcf = cc_shadowWHPBInfo.z;\nif (pcf > 2.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft5X(pos);\n} else if (pcf > 1.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft3X(pos);\n} else if (pcf > 0.9) {\nrealtimeShadow = CCGetDirLightShadowFactorSoft(pos);\n}else {\nrealtimeShadow = CCGetDirLightShadowFactorHard(pos);\n}\nreturn mix(realtimeShadow, 1.0, cc_shadowNFLSInfo.w);\n}\n#endif\n#if CC_USE_IBL\nlayout(set = 0, binding = 4) uniform samplerCube cc_environment;\nvec4 fragTextureLod (sampler2D tex, vec2 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec4 fragTextureLod (samplerCube tex, vec3 coord, float lod) {\nreturn textureLod(tex, coord, lod);\n}\nvec3 unpackRGBE (vec4 rgbe) {\nreturn rgbe.rgb * pow(1.1, rgbe.a * 255.0 - 128.0);\n}\n#if CC_USE_DIFFUSEMAP\nlayout(set = 0, binding = 6) uniform samplerCube cc_diffuseMap;\n#endif\n#endif\nfloat GGXMobile (float roughness, float NoH, vec3 H, vec3 N) {\nvec3 NxH = cross(N, H);\nfloat OneMinusNoHSqr = dot(NxH, NxH);\nfloat a = roughness * roughness;\nfloat n = NoH * a;\nfloat p = a / (OneMinusNoHSqr + n * n);\nreturn p * p;\n}\nfloat CalcSpecular (float roughness, float NoH, vec3 H, vec3 N) {\nreturn (roughness * 0.25 + 0.25) * GGXMobile(roughness, NoH, H, N);\n}\nvec3 BRDFApprox (vec3 specular, float roughness, float NoV) {\nconst vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);\nconst vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);\nvec4 r = roughness * c0 + c1;\nfloat a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;\nvec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;\nAB.y *= clamp(50.0 * specular.g, 0.0, 1.0);\nreturn specular * AB.x + AB.y;\n}\n#if USE_REFLECTION_DENOISE\nvec3 GetEnvReflectionWithMipFiltering(vec3 R, float roughness, float mipCount, float denoiseIntensity) {\n#if CC_USE_IBL\nfloat mip = roughness * mipCount;\nfloat delta = (dot(dFdx(R), dFdy(R))) * 1000.0;\nfloat mipBias = mix(0.0, 5.0, clamp(delta, 0.0, 1.0));\nvec4 biased = fragTextureLod(cc_environment, R, mip + mipBias);\nvec4 filtered = texture(cc_environment, R);\n#if CC_USE_IBL == 2\nbiased.rgb = unpackRGBE(biased);\nfiltered.rgb = unpackRGBE(filtered);\n#else\nbiased.rgb = SRGBToLinear(biased.rgb);\nfiltered.rgb = SRGBToLinear(filtered.rgb);\n#endif\nreturn mix(biased.rgb, filtered.rgb, denoiseIntensity);\n#else\nreturn vec3(0.0, 0.0, 0.0);\n#endif\n}\n#endif\nstruct StandardSurface {\nvec4 albedo;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nvec3 position, position_fract_part;\n#else\nvec3 position;\n#endif\nvec3 normal;\nvec3 emissive;\nvec3 lightmap;\nfloat lightmap_test;\nfloat roughness;\nfloat metallic;\nfloat occlusion;\nfloat specularIntensity;\n#if CC_RECEIVE_SHADOW\nvec2 shadowBias;\n#endif\n};\nvec4 CCStandardShadingBase (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.08 * s.specularIntensity), s.albedo.rgb, s.metallic);\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 L = normalize(-cc_mainLitDir.xyz);\nvec3 H = normalize(L + V);\nfloat NH = max(dot(N, H), 0.0);\nfloat NL = max(dot(N, L), 0.0);\nvec3 finalColor = NL * cc_mainLitColor.rgb * cc_mainLitColor.w;\nvec3 diffuseContrib = diffuse / PI;\nvec3 specularContrib = specular * CalcSpecular(s.roughness, NH, H, N);\nvec3 dirlightContrib = (diffuseContrib + specularContrib);\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (NL > 0.0 && cc_mainLitDir.w > 0.0) {\nif (cc_shadowLPNNInfo.w > 0.0) {\nshadow = CCCSMFactorBase(position, N, s.shadowBias);\n} else {\nshadow = CCShadowFactorBase(shadowPos, N, s.shadowBias);\n}\n}\n#endif\ndirlightContrib *= shadow;\nfinalColor *= dirlightContrib;\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nif (s.lightmap_test > EPSILON_LOWP) {\nfinalColor = diffuse * s.lightmap.rgb * shadow;\n}\n#endif\nfloat fAmb = 0.5 - N.y * 0.5;\nvec3 ambDiff = mix(cc_ambientSky.rgb, cc_ambientGround.rgb, fAmb);\n#if CC_USE_IBL\n#if CC_USE_DIFFUSEMAP\nvec4 diffuseMap = texture(cc_diffuseMap, N);\n#if CC_USE_DIFFUSEMAP == 2\nambDiff = unpackRGBE(diffuseMap);\n#else\nambDiff = SRGBToLinear(diffuseMap.rgb);\n#endif\n#endif\nvec3 R = normalize(reflect(-V, N));\n#if USE_REFLECTION_DENOISE\nvec3 env = GetEnvReflectionWithMipFiltering(R, s.roughness, cc_ambientGround.w, 0.6);\n#else\nvec4 envmap = fragTextureLod(cc_environment, R, s.roughness * cc_ambientGround.w);\n#if CC_USE_IBL == 2\nvec3 env = unpackRGBE(envmap);\n#else\nvec3 env = SRGBToLinear(envmap.rgb);\n#endif\n#endif\nfinalColor += env * cc_ambientSky.w * specular * s.occlusion;\n#endif\nfinalColor += ambDiff.rgb * cc_ambientSky.w * diffuse * s.occlusion;\nfinalColor += s.emissive;\nreturn vec4(finalColor, s.albedo.a);\n}\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nlayout(location = 1) in highp vec4 v_shadowPos;\n#if CC_RECEIVE_SHADOW\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nlayout(location = 9) in vec3 v_luv;\nlayout(set = 2, binding = 10) uniform sampler2D cc_lightingMap;\n#endif\nlayout(location = 3) in vec3 v_position;\nlayout(location = 5) in vec2 v_uv;\n#if HAS_SECOND_UV\nlayout(location = 6) in mediump vec2 v_uv1;\n#endif\nlayout(location = 4) in mediump vec3 v_normal;\n#if CC_RECEIVE_SHADOW\nlayout(location = 7) in mediump vec2 v_shadowBias;\n#endif\n#if USE_VERTEX_COLOR\nlayout(location = 2) in lowp vec4 v_color;\n#endif\n#if USE_ALBEDO_MAP\nlayout(set = 1, binding = 1) uniform sampler2D albedoMap;\n#endif\n#if USE_NORMAL_MAP\nlayout(location = 8) in mediump vec4 v_tangent;\nlayout(set = 1, binding = 2) uniform sampler2D normalMap;\n#endif\n#if USE_PBR_MAP\nlayout(set = 1, binding = 3) uniform sampler2D pbrMap;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nlayout(set = 1, binding = 4) uniform sampler2D metallicRoughnessMap;\n#endif\n#if USE_OCCLUSION_MAP\nlayout(set = 1, binding = 5) uniform sampler2D occlusionMap;\n#endif\n#if USE_EMISSIVE_MAP\nlayout(set = 1, binding = 6) uniform sampler2D emissiveMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvoid surf (out StandardSurface s) {\nvec4 baseColor = albedo;\n#if USE_VERTEX_COLOR\nbaseColor.rgb *= SRGBToLinear(v_color.rgb);\nbaseColor.a *= v_color.a;\n#endif\n#if USE_ALBEDO_MAP\nvec4 texColor = texture(albedoMap, ALBEDO_UV);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\nbaseColor *= texColor;\n#endif\ns.albedo = baseColor;\ns.albedo.rgb *= albedoScaleAndCutoff.xyz;\n#if USE_ALPHA_TEST\nif (s.albedo.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\n#if CC_USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD\nvec4 lightColor = texture(cc_lightingMap, v_luv.xy);\ns.lightmap = lightColor.xyz * v_luv.z;\ns.lightmap_test = v_luv.z;\n#endif\ns.normal = v_normal;\n#if CC_RECEIVE_SHADOW\ns.shadowBias = v_shadowBias;\n#endif\n#if USE_NORMAL_MAP\nvec3 nmmp = texture(normalMap, NORMAL_UV).xyz - vec3(0.5);\nvec3 bitangent = cross(v_normal, v_tangent.xyz) * v_tangent.w;\ns.normal =\n(nmmp.x * emissiveScaleParam.w) * normalize(v_tangent.xyz) +\n(nmmp.y * emissiveScaleParam.w) * normalize(bitangent) +\nnmmp.z * normalize(s.normal);\n#endif\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\npackHighpData(s.position, s.position_fract_part, v_position);\n#else\ns.position = v_position;\n#endif\nvec4 pbr = pbrParams;\n#if USE_PBR_MAP\nvec4 res = texture(pbrMap, PBR_UV);\npbr.x *= res.r;\npbr.y *= res.g;\npbr.z *= res.b;\npbr.w *= res.a;\n#endif\n#if USE_METALLIC_ROUGHNESS_MAP\nvec4 metallicRoughness = texture(metallicRoughnessMap, PBR_UV);\npbr.z *= metallicRoughness.b;\npbr.y *= metallicRoughness.g;\n#endif\n#if USE_OCCLUSION_MAP\npbr.x *= texture(occlusionMap, PBR_UV).r;\n#endif\ns.occlusion = pbr.x;\ns.roughness = pbr.y;\ns.specularIntensity = 0.5;\ns.metallic = pbr.z;\ns.emissive = emissive.rgb * emissiveScaleParam.xyz;\n#if USE_EMISSIVE_MAP\ns.emissive *= SRGBToLinear(texture(emissiveMap, EMISSIVE_UV).rgb);\n#endif\n}\n#if CC_FORWARD_ADD\n#if CC_PIPELINE_TYPE == 0\n#define LIGHTS_PER_PASS 1\n#else\n#define LIGHTS_PER_PASS 10\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nlayout(set = 2, binding = 1) uniform CCForwardLight {\nhighp vec4 cc_lightPos[LIGHTS_PER_PASS];\nvec4 cc_lightColor[LIGHTS_PER_PASS];\nvec4 cc_lightSizeRangeAngle[LIGHTS_PER_PASS];\nvec4 cc_lightDir[LIGHTS_PER_PASS];\n};\n#endif\nfloat SmoothDistAtt (float distSqr, float invSqrAttRadius) {\nfloat factor = distSqr * invSqrAttRadius;\nfloat smoothFactor = clamp(1.0 - factor * factor, 0.0, 1.0);\nreturn smoothFactor * smoothFactor;\n}\nfloat GetDistAtt (float distSqr, float invSqrAttRadius) {\nfloat attenuation = 1.0 / max(distSqr, 0.01*0.01);\nattenuation *= SmoothDistAtt(distSqr , invSqrAttRadius);\nreturn attenuation;\n}\nfloat GetAngleAtt (vec3 L, vec3 litDir, float litAngleScale, float litAngleOffset) {\nfloat cd = dot(litDir, L);\nfloat attenuation = clamp(cd * litAngleScale + litAngleOffset, 0.0, 1.0);\nreturn (attenuation * attenuation);\n}\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 0\nvec4 CCStandardShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.0);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nint numLights = CC_PIPELINE_TYPE == 0 ? LIGHTS_PER_PASS : int(cc_lightDir[0].w);\nfor (int i = 0; i < LIGHTS_PER_PASS; i++) {\nif (i >= numLights) break;\nvec3 SLU = cc_lightPos[i].xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.0);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = cc_lightSizeRangeAngle[i].x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = litRadiusSqr / max(litRadiusSqr, distSqr);\nfloat attRadiusSqrInv = 1.0 / max(cc_lightSizeRangeAngle[i].y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (cc_lightPos[i].w > 0.0) {\nfloat cosInner = max(dot(-cc_lightDir[i].xyz, SL), 0.01);\nfloat cosOuter = cc_lightSizeRangeAngle[i].z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -cc_lightDir[i].xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = cc_lightColor[i].rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (cc_lightPos[i].w > 0.0 && cc_lightSizeRangeAngle[i].w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * cc_lightColor[i].w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nlayout(set = 1, binding = 7) readonly buffer b_ccLightsBuffer { vec4 b_ccLights[]; };\nlayout(set = 1, binding = 8) readonly buffer b_clusterLightIndicesBuffer { uint b_clusterLightIndices[]; };\nlayout(set = 1, binding = 9) readonly buffer b_clusterLightGridBuffer { uvec4 b_clusterLightGrid[]; };\nstruct CCLight\n{\nvec4 cc_lightPos;\nvec4 cc_lightColor;\nvec4 cc_lightSizeRangeAngle;\nvec4 cc_lightDir;\n};\nstruct Cluster\n{\nvec3 minBounds;\nvec3 maxBounds;\n};\nstruct LightGrid\n{\nuint offset;\nuint ccLights;\n};\nCCLight getCCLight(uint i)\n{\nCCLight light;\nlight.cc_lightPos = b_ccLights[4u * i + 0u];\nlight.cc_lightColor = b_ccLights[4u * i + 1u];\nlight.cc_lightSizeRangeAngle = b_ccLights[4u * i + 2u];\nlight.cc_lightDir = b_ccLights[4u * i + 3u];\nreturn light;\n}\nLightGrid getLightGrid(uint cluster)\n{\nuvec4 gridvec = b_clusterLightGrid[cluster];\nLightGrid grid;\ngrid.offset = gridvec.x;\ngrid.ccLights = gridvec.y;\nreturn grid;\n}\nuint getGridLightIndex(uint start, uint offset)\n{\nreturn b_clusterLightIndices[start + offset];\n}\nuint getClusterZIndex(vec4 worldPos)\n{\nfloat scale = float(24) / log(cc_nearFar.y / cc_nearFar.x);\nfloat bias = -(float(24) * log(cc_nearFar.x) / log(cc_nearFar.y / cc_nearFar.x));\nfloat eyeDepth = -(cc_matView * worldPos).z;\nuint zIndex = uint(max(log(eyeDepth) * scale + bias, 0.0));\nreturn zIndex;\n}\nuint getClusterIndex(vec4 fragCoord, vec4 worldPos)\n{\nuint zIndex = getClusterZIndex(worldPos);\nfloat clusterSizeX = ceil(cc_viewPort.z / float(16));\nfloat clusterSizeY = ceil(cc_viewPort.w / float(8));\nuvec3 indices = uvec3(uvec2(fragCoord.xy / vec2(clusterSizeX, clusterSizeY)), zIndex);\nuint cluster = (16u * 8u) * indices.z + 16u * indices.y + indices.x;\nreturn cluster;\n}\nvec4 CCClusterShadingAdditive (StandardSurface s, vec4 shadowPos) {\nvec3 diffuse = s.albedo.rgb * (1.0 - s.metallic);\nvec3 specular = mix(vec3(0.04), s.albedo.rgb, s.metallic);\nvec3 diffuseContrib = diffuse / PI;\nvec3 position;\n#if CC_PLATFORM_ANDROID_AND_WEBGL && CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES\nposition = unpackHighpData(s.position, s.position_fract_part);\n#else\nposition = s.position;\n#endif\nvec3 N = normalize(s.normal);\nvec3 V = normalize(cc_cameraPos.xyz - position);\nfloat NV = max(abs(dot(N, V)), 0.001);\nspecular = BRDFApprox(specular, s.roughness, NV);\nvec3 finalColor = vec3(0.0);\nuint cluster = getClusterIndex(gl_FragCoord, vec4(position, 1.0));\nLightGrid grid = getLightGrid(cluster);\nuint numLights = grid.ccLights;\nfor (uint i = 0u; i < 100u; i++) {\nif (i >= numLights) break;\nuint lightIndex = getGridLightIndex(grid.offset, i);\nCCLight light = getCCLight(lightIndex);\nvec3 SLU = light.cc_lightPos.xyz - position;\nvec3 SL = normalize(SLU);\nvec3 SH = normalize(SL + V);\nfloat SNL = max(dot(N, SL), 0.001);\nfloat SNH = max(dot(N, SH), 0.0);\nfloat distSqr = dot(SLU, SLU);\nfloat litRadius = light.cc_lightSizeRangeAngle.x;\nfloat litRadiusSqr = litRadius * litRadius;\nfloat illum = PI * (litRadiusSqr / max(litRadiusSqr , distSqr));\nfloat attRadiusSqrInv = 1.0 / max(light.cc_lightSizeRangeAngle.y, 0.01);\nattRadiusSqrInv *= attRadiusSqrInv;\nfloat att = GetDistAtt(distSqr, attRadiusSqrInv);\nvec3 lspec = specular * CalcSpecular(s.roughness, SNH, SH, N);\nif (light.cc_lightPos.w > 0.0) {\nfloat cosInner = max(dot(-light.cc_lightDir.xyz, SL), 0.01);\nfloat cosOuter = light.cc_lightSizeRangeAngle.z;\nfloat litAngleScale = 1.0 / max(0.001, cosInner - cosOuter);\nfloat litAngleOffset = -cosOuter * litAngleScale;\natt *= GetAngleAtt(SL, -light.cc_lightDir.xyz, litAngleScale, litAngleOffset);\n}\nvec3 lightColor = light.cc_lightColor.rgb;\nfloat shadow = 1.0;\n#if CC_RECEIVE_SHADOW\nif (light.cc_lightPos.w > 0.0) {\nshadow = CCSpotShadowFactorBase(shadowPos, position, s.shadowBias);\n}\n#endif\nlightColor *= shadow;\nfinalColor += SNL * lightColor * light.cc_lightColor.w * illum * att * (diffuseContrib + lspec);\n}\nreturn vec4(finalColor, 0.0);\n}\n#endif\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\n#if CC_ENABLE_CLUSTERED_LIGHT_CULLING == 1\nvec4 color = CCClusterShadingAdditive(s, v_shadowPos);\n#else\nvec4 color = CCStandardShadingAdditive(s, v_shadowPos);\n#endif\nfragColorX = CCFragOutput(color);\n}\n#elif (CC_PIPELINE_TYPE == 0 || CC_FORCE_FORWARD_SHADING)\nlayout(location = 0) out vec4 fragColorX;\nvoid main () {\nStandardSurface s; surf(s);\nvec4 color = CCStandardShadingBase(s, v_shadowPos);\nCC_APPLY_FOG(color, s.position.xyz);\nfragColorX = CCFragOutput(color);\n}\n#elif CC_PIPELINE_TYPE == 1\nvec2 signNotZero(vec2 v) {\nreturn vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);\n}\nvec2 float32x3_to_oct(in vec3 v) {\nvec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));\nreturn (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;\n}\nlayout(location = 0) out vec4 fragColor0;\nlayout(location = 1) out vec4 fragColor1;\nlayout(location = 2) out vec4 fragColor2;\nvoid main () {\nStandardSurface s; surf(s);\nfragColor0 = s.albedo;\nfragColor1 = vec4(float32x3_to_oct(s.normal), s.roughness, s.metallic);\nfragColor2 = vec4(s.emissive, s.occlusion);\n}\n#endif", }, { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nlayout(location = 14) in vec2 a_texCoord1;\n#endif\nlayout(location = 0) out vec2 v_uv;\n#if HAS_SECOND_UV\nlayout(location = 1) out vec2 v_uv1;\n#endif\nlayout(location = 2) out vec4 v_worldPos;\nlayout(location = 3) out float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrixFull(out mat4 matWorld, out mat4 matWorldIT)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\nmatWorldIT = matWorld;\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\nmatWorldIT = matWorld;\n#else\nmatWorld = cc_matWorld;\nmatWorldIT = cc_matWorldIT;\n#endif\n}\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#if HAS_SECOND_UV || CC_USE_LIGHTMAP\nlayout(location = 14) in vec2 a_texCoord1;\n#endif\nlayout(location = 0) out vec2 v_uv;\n#if HAS_SECOND_UV\nlayout(location = 1) out vec2 v_uv1;\n#endif\nlayout(location = 2) out vec4 v_worldPos;\nlayout(location = 3) out float v_clip_depth;\nvec4 vert () {\nStandardVertInput In;\nCCVertInput(In);\nmat4 matWorld, matWorldIT;\nCCGetWorldMatrixFull(matWorld, matWorldIT);\nv_worldPos = matWorld * In.position;\nvec4 clipPos = cc_matLightViewProj * v_worldPos;\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if HAS_SECOND_UV\nv_uv1 = a_texCoord1 * tilingOffset.xy + tilingOffset.zw;\n#endif\nv_clip_depth = clipPos.z / clipPos.w * 0.5 + 0.5;\nreturn clipPos;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nlayout(set = 1, binding = 0) uniform Constants {\nvec4 tilingOffset;\nvec4 albedo;\nvec4 albedoScaleAndCutoff;\nvec4 pbrParams;\nvec4 emissive;\nvec4 emissiveScaleParam;\n};\nvec4 packDepthToRGBA (float depth) {\nvec4 ret = vec4(1.0, 255.0, 65025.0, 16581375.0) * depth;\nret = fract(ret);\nret -= vec4(ret.yzw, 0.0) / 255.0;\nreturn ret;\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nfloat GetLinearDepthFromViewSpace(vec3 viewPos, float near, float far) {\nfloat dist = length(viewPos);\nreturn (dist - near) / (far - near);\n}\nfloat CCGetLinearDepth(vec3 worldPos) {\nvec4 viewStartPos = cc_matLightView * vec4(worldPos.xyz, 1.0);\nreturn GetLinearDepthFromViewSpace(viewStartPos.xyz, cc_shadowNFLSInfo.x, cc_shadowNFLSInfo.y);\n}\n#if CC_RECEIVE_SHADOW\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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 = 0, binding = 3) uniform highp sampler2D cc_shadowMap;\nlayout(set = 0, binding = 5) uniform highp sampler2D cc_spotLightingMap;\n#endif\nlayout(location = 0) in vec2 v_uv;\n#if HAS_SECOND_UV\nlayout(location = 1) in vec2 v_uv1;\n#endif\nlayout(location = 2) in vec4 v_worldPos;\nlayout(location = 3) in float v_clip_depth;\n#if USE_ALBEDO_MAP\nlayout(set = 1, binding = 1) uniform sampler2D albedoMap;\n#endif\n#if USE_ALPHA_TEST\n#endif\nvec4 frag () {\nvec4 baseColor = albedo;\n#if USE_ALBEDO_MAP\nbaseColor *= texture(albedoMap, ALBEDO_UV);\n#endif\n#if USE_ALPHA_TEST\nif (baseColor.ALPHA_TEST_CHANNEL < albedoScaleAndCutoff.w) discard;\n#endif\nif(cc_shadowLPNNInfo.x > 0.000001 && cc_shadowLPNNInfo.x < 1.999999) {\nif (cc_shadowNFLSInfo.z > 0.000001) {\nreturn vec4(CCGetLinearDepth(v_worldPos.xyz), 1.0, 1.0, 1.0);\n}\n}\nif (cc_shadowLPNNInfo.y > 0.000001) {\nreturn packDepthToRGBA(v_clip_depth);\n}\nreturn vec4(v_clip_depth, 1.0, 1.0, 1.0);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], @@ -108,25 +108,25 @@ export const glsl4 = [ ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nlayout(location = 14) in lowp vec4 a_color;\nlayout(location = 1) out lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nlayout(location = 2) out vec2 v_uv;\nlayout(set = 1, binding = 0) uniform TexCoords {\nvec4 tilingOffset;\n};\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) out float v_fog_factor;\n#endif\nvoid CC_TRANSFER_FOG(vec4 pos) {\n#if !CC_USE_ACCURATE_FOG\nCC_TRANSFER_FOG_BASE(pos, v_fog_factor);\n#endif\n}\n#if USE_VERTEX_COLOR\nlayout(location = 14) in lowp vec4 a_color;\nlayout(location = 1) out lowp vec4 v_color;\n#endif\n#if USE_TEXTURE\nlayout(location = 2) out vec2 v_uv;\nlayout(set = 1, binding = 0) uniform TexCoords {\nvec4 tilingOffset;\n};\n#endif\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\n#if USE_TEXTURE\nv_uv = a_texCoord * tilingOffset.xy + tilingOffset.zw;\n#if SAMPLE_FROM_RT\nv_uv = cc_cameraPos.w > 1.0 ? vec2(v_uv.x, 1.0 - v_uv.y) : v_uv;\n#endif\n#endif\n#if USE_VERTEX_COLOR\nv_color = a_color;\n#endif\nCC_TRANSFER_FOG(matWorld * position);\nreturn cc_matProj * (cc_matView * matWorld) * position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision highp float;\nvec3 ACESToneMap (vec3 color) {\ncolor = min(color, vec3(8.0));\nconst float A = 2.51;\nconst float B = 0.03;\nconst float C = 2.43;\nconst float D = 0.59;\nconst float E = 0.14;\nreturn (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nvec4 CCFragOutput (vec4 color) {\n#if CC_USE_HDR\ncolor.rgb = ACESToneMap(color.rgb);\n#endif\ncolor.rgb = sqrt(color.rgb);\nreturn color;\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if CC_USE_FOG != 4\nfloat LinearFog(vec4 pos, vec3 cameraPos, float fogStart, float fogEnd) {\nvec4 wPos = pos;\nfloat cam_dis = distance(cameraPos, wPos.xyz);\nreturn clamp((fogEnd - cam_dis) / (fogEnd - fogStart), 0., 1.);\n}\nfloat ExpFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * fogDensity);\nreturn f;\n}\nfloat ExpSquaredFog(vec4 pos, vec3 cameraPos, float fogStart, float fogDensity, float fogAtten) {\nvec4 wPos = pos;\nfloat cam_dis = max(distance(cameraPos, wPos.xyz) - fogStart, 0.0) / fogAtten * 4.;\nfloat f = exp(-cam_dis * cam_dis * fogDensity * fogDensity);\nreturn f;\n}\nfloat LayeredFog(vec4 pos, vec3 cameraPos, float fogTop, float fogRange, float fogAtten) {\nvec4 wPos = pos;\nvec3 camWorldProj = cameraPos.xyz;\ncamWorldProj.y = 0.;\nvec3 worldPosProj = wPos.xyz;\nworldPosProj.y = 0.;\nfloat fDeltaD = distance(worldPosProj, camWorldProj) / fogAtten * 2.0;\nfloat fDeltaY, fDensityIntegral;\nif (cameraPos.y > fogTop) {\nif (wPos.y < fogTop) {\nfDeltaY = (fogTop - wPos.y) / fogRange * 2.0;\nfDensityIntegral = fDeltaY * fDeltaY * 0.5;\n}\nelse {\nfDeltaY = 0.;\nfDensityIntegral = 0.;\n}\n}\nelse {\nif (wPos.y < fogTop) {\nfloat fDeltaA = (fogTop - cameraPos.y) / fogRange * 2.;\nfloat fDeltaB = (fogTop - wPos.y) / fogRange * 2.;\nfDeltaY = abs(fDeltaA - fDeltaB);\nfDensityIntegral = abs((fDeltaA * fDeltaA * 0.5) - (fDeltaB * fDeltaB * 0.5));\n}\nelse {\nfDeltaY = abs(fogTop - cameraPos.y) / fogRange * 2.;\nfDensityIntegral = abs(fDeltaY * fDeltaY * 0.5);\n}\n}\nfloat fDensity;\nif (fDeltaY != 0.) {\nfDensity = (sqrt(1.0 + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;\n}\nelse {\nfDensity = 0.;\n}\nfloat f = exp(-fDensity);\nreturn f;\n}\n#endif\nvoid CC_TRANSFER_FOG_BASE(vec4 pos, out float factor)\n{\n#if CC_USE_FOG == 0\nfactor = LinearFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.y);\n#elif CC_USE_FOG == 1\nfactor = ExpFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 2\nfactor = ExpSquaredFog(pos, cc_cameraPos.xyz, cc_fogBase.x, cc_fogBase.z, cc_fogAdd.z);\n#elif CC_USE_FOG == 3\nfactor = LayeredFog(pos, cc_cameraPos.xyz, cc_fogAdd.x, cc_fogAdd.y, cc_fogAdd.z);\n#else\nfactor = 1.0;\n#endif\n}\nvoid CC_APPLY_FOG_BASE(inout vec4 color, float factor) {\ncolor = vec4(mix(cc_fogColor.rgb, color.rgb, factor), color.a);\n}\n#if !CC_USE_ACCURATE_FOG\nlayout(location = 0) in float v_fog_factor;\n#endif\nvoid CC_APPLY_FOG(inout vec4 color) {\n#if !CC_USE_ACCURATE_FOG\nCC_APPLY_FOG_BASE(color, v_fog_factor);\n#endif\n}\nvoid CC_APPLY_FOG(inout vec4 color, vec3 worldPos) {\n#if CC_USE_ACCURATE_FOG\nfloat factor;\nCC_TRANSFER_FOG_BASE(vec4(worldPos, 1.0), factor);\n#else\nfloat factor = v_fog_factor;\n#endif\nCC_APPLY_FOG_BASE(color, factor);\n}\n#if USE_ALPHA_TEST\n#endif\n#if USE_TEXTURE\nlayout(location = 2) in vec2 v_uv;\nlayout(set = 1, binding = 2) uniform sampler2D mainTexture;\n#endif\nlayout(set = 1, binding = 1) uniform Constant {\nvec4 mainColor;\nvec4 colorScaleAndCutoff;\n};\n#if USE_VERTEX_COLOR\nlayout(location = 1) in lowp vec4 v_color;\n#endif\nvec4 frag () {\nvec4 o = mainColor;\no.rgb *= colorScaleAndCutoff.xyz;\n#if USE_VERTEX_COLOR\no.rgb *= SRGBToLinear(v_color.rgb);\no.a *= v_color.a;\n#endif\n#if USE_TEXTURE\nvec4 texColor = texture(mainTexture, v_uv);\ntexColor.rgb = SRGBToLinear(texColor.rgb);\no *= texColor;\n#endif\n#if USE_ALPHA_TEST\nif (o.ALPHA_TEST_CHANNEL < colorScaleAndCutoff.w) discard;\n#endif\nCC_APPLY_FOG(o);\nreturn CCFragOutput(o);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\nvec3 SRGBToLinear (vec3 gamma) {\nreturn gamma * gamma;\n}\nlayout(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform BloomUBO {\nmediump vec4 texSize;\n};\nlayout(set = 1, binding = 1) uniform sampler2D outputResultMap;\nlayout(location = 0) out vec4 fragColor;\nfloat luminance(vec3 color) {\nreturn dot(color, vec3(0.2126, 0.7152, 0.0722));\n}\nvoid main() {\nvec3 color = texture(outputResultMap, v_uv).xyz;\nif (luminance(SRGBToLinear(color)) > texSize.z) {\nfragColor = vec4(color, 1.0);\n} else {\nfragColor = vec4(0.0, 0.0, 0.0, 1.0);\n}\n}", }, { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform BloomUBO {\nmediump vec4 texSize;\n};\nlayout(set = 1, binding = 1) uniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvec3 downsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main()\n{\nvec3 result = downsample4taps(v_uv, 1.0 / texSize.xy).rgb;\nfragColor = vec4(result, 1.0);\n}", }, { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform BloomUBO {\nmediump vec4 texSize;\n};\nlayout(set = 1, binding = 1) uniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvec3 upsample4taps(vec2 uv, vec2 halfpixel) {\nvec3 sum = texture(bloomTexture, uv + vec2(-halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(halfpixel.x, -halfpixel.y)).xyz;\nsum += texture(bloomTexture, uv + vec2(-halfpixel.x, -halfpixel.y)).xyz;\nreturn sum / 4.0;\n}\nvoid main() {\nvec3 result = upsample4taps(v_uv, 0.5 / texSize.xy).rgb;\nfragColor = vec4(result, 1.0);\n}", }, { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform BloomUBO {\nmediump vec4 texSize;\n};\nlayout(set = 1, binding = 1) uniform sampler2D outputResultMap;\nlayout(set = 1, binding = 2) uniform sampler2D bloomTexture;\nlayout(location = 0) out vec4 fragColor;\nvoid main() {\nvec4 hdrColor = texture(outputResultMap, v_uv);\nvec3 bloomColor = texture(bloomTexture, v_uv).rgb;\nvec3 result = hdrColor.rgb + bloomColor * texSize.w * hdrColor.a;\nfragColor = vec4(result, hdrColor.a);\n}", } ], @@ -138,13 +138,13 @@ export const glsl4 = [ ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\nlayout(location = 0) out float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout vec4 In)\n{\nIn = vec4(a_position, 1.0);\n#if CC_USE_MORPH\napplyMorph(In);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if !USE_INSTANCING\n#if USE_BATCHING\nlayout(set = 2, binding = 0) uniform CCLocalBatched {\nhighp mat4 cc_matWorlds[10];\n};\n#else\nlayout(set = 2, binding = 0) uniform CCLocal {\nhighp mat4 cc_matWorld;\nhighp mat4 cc_matWorldIT;\nhighp vec4 cc_lightingMapUVParam;\nhighp vec4 cc_localShadowBias;\n};\n#endif\n#endif\nvoid CCGetWorldMatrix(out mat4 matWorld)\n{\n#if USE_INSTANCING\nmatWorld = mat4(\nvec4(a_matWorld0.xyz, 0.0),\nvec4(a_matWorld1.xyz, 0.0),\nvec4(a_matWorld2.xyz, 0.0),\nvec4(a_matWorld0.w, a_matWorld1.w, a_matWorld2.w, 1.0)\n);\n#elif USE_BATCHING\nmatWorld = cc_matWorlds[int(a_dyn_batch_id)];\n#else\nmatWorld = cc_matWorld;\n#endif\n}\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\nlayout(location = 0) out float v_dist;\nvec4 vert () {\nvec4 position;\nCCVertInput(position);\nmat4 matWorld;\nCCGetWorldMatrix(matWorld);\nvec3 P = (matWorld * position).xyz;\nvec3 L = cc_mainLitDir.xyz;\nvec3 N = cc_planarNDInfo.xyz;\nfloat d = cc_planarNDInfo.w + 0.001;\nfloat dist = (-d - dot(P, N)) / (dot(L, N) + 0.0001);\nvec3 shadowPos = P + L * dist;\nvec3 view = normalize(cc_cameraPos.xyz - shadowPos);\nfloat viewLength = length(cc_cameraPos.xyz - shadowPos);\nshadowPos += view * min(1.0, 0.005 * viewLength);\nposition = cc_matProj * cc_matView * vec4(shadowPos, 1.0);\nv_dist = dist;\nreturn position;\n}\nvoid main() { gl_Position = vert(); }", "frag": "\nprecision mediump float;\nlayout(set = 0, binding = 2) uniform CCShadow {\nhighp mat4 cc_matLightPlaneProj;\nhighp mat4 cc_matLightView;\nhighp mat4 cc_matLightViewProj;\nhighp vec4 cc_shadowInvProjDepthInfo;\nhighp vec4 cc_shadowProjDepthInfo;\nhighp vec4 cc_shadowProjInfo;\nmediump vec4 cc_shadowNFLSInfo;\nmediump vec4 cc_shadowWHPBInfo;\nmediump vec4 cc_shadowLPNNInfo;\nlowp vec4 cc_shadowColor;\nmediump vec4 cc_planarNDInfo;\nhighp mat4 cc_matCSMView[4];\nhighp mat4 cc_matCSMViewProj[4];\nhighp mat4 cc_matCSMViewProjAtlas[4];\nhighp vec4 cc_csmProjDepthInfo[4];\nhighp vec4 cc_csmProjInfo[4];\nhighp vec4 cc_csmSplitsInfo;\nhighp vec4 cc_csmInfo;\n};\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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 float v_dist;\nvec4 frag () {\nif(v_dist < 0.0)\ndiscard;\nreturn CCFragOutput(cc_shadowColor);\n}\nlayout(location = 0) out vec4 cc_FragColor;\nvoid main() { cc_FragColor = frag(); }", } ], [ { - "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[30 * 3];\n};\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", + "vert": "#extension GL_EXT_shader_explicit_arithmetic_types_int32: require\nprecision highp float;\n#define QUATER_PI 0.78539816340\n#define HALF_PI 1.57079632679\n#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI4 12.5663706144\n#define INV_QUATER_PI 1.27323954474\n#define INV_HALF_PI 0.63661977237\n#define INV_PI 0.31830988618\n#define INV_PI2 0.15915494309\n#define INV_PI4 0.07957747155\n#define EPSILON 1e-6\n#define EPSILON_LOWP 1e-4\n#define LOG2 1.442695\n#define EXP_VALUE 2.71828183f\n#define FP_MAX 65504.0\n#define FP_SCALE 0.0009765625\n#define FP_SCALE_INV 1024.0\n#define GRAY_VECTOR vec3(0.299, 0.587, 0.114)\nhighp float decode32 (highp vec4 rgba) {\nrgba = rgba * 255.0;\nhighp float Sign = 1.0 - (step(128.0, (rgba[3]) + 0.5)) * 2.0;\nhighp float Exponent = 2.0 * (mod(float(int((rgba[3]) + 0.5)), 128.0)) + (step(128.0, (rgba[2]) + 0.5)) - 127.0;\nhighp float Mantissa = (mod(float(int((rgba[2]) + 0.5)), 128.0)) * 65536.0 + rgba[1] * 256.0 + rgba[0] + 8388608.0;\nreturn Sign * exp2(Exponent - 23.0) * Mantissa;\n}\nstruct StandardVertInput {\nhighp vec4 position;\nvec3 normal;\nvec4 tangent;\n};\nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec3 a_normal;\nlayout(location = 2) in vec2 a_texCoord;\nlayout(location = 3) in vec4 a_tangent;\n#if CC_USE_SKINNING\nlayout(location = 4) in u32vec4 a_joints;\nlayout(location = 5) in vec4 a_weights;\n#endif\n#if USE_INSTANCING\n#if CC_USE_BAKED_ANIMATION\nlayout(location = 6) in highp vec4 a_jointAnimInfo;\n#endif\nlayout(location = 7) in vec4 a_matWorld0;\nlayout(location = 8) in vec4 a_matWorld1;\nlayout(location = 9) in vec4 a_matWorld2;\n#if CC_USE_LIGHTMAP\nlayout(location = 10) in vec4 a_lightingMapUVParam;\n#endif\n#if CC_RECEIVE_SHADOW\nlayout(location = 11) in vec2 a_localShadowBias;\n#endif\n#elif USE_BATCHING\nlayout(location = 12) in float a_dyn_batch_id;\n#endif\n#if CC_USE_MORPH\nint getVertexId() {\nreturn gl_VertexIndex;\n}\n#endif\n#if CC_USE_MORPH\nlayout(set = 2, binding = 4) uniform CCMorph {\nvec4 cc_displacementWeights[15];\nvec4 cc_displacementTextureInfo;\n};\n#if CC_MORPH_TARGET_HAS_POSITION\nlayout(set = 2, binding = 7) uniform sampler2D cc_PositionDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nlayout(set = 2, binding = 8) uniform sampler2D cc_NormalDisplacements;\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nlayout(set = 2, binding = 9) uniform sampler2D cc_TangentDisplacements;\n#endif\nvec2 getPixelLocation(vec2 textureResolution, int pixelIndex) {\nfloat pixelIndexF = float(pixelIndex);\nfloat x = mod(pixelIndexF, textureResolution.x);\nfloat y = floor(pixelIndexF / textureResolution.x);\nreturn vec2(x, y);\n}\nvec2 getPixelCoordFromLocation(vec2 location, vec2 textureResolution) {\nreturn (vec2(location.x, location.y) + .5) / textureResolution;\n}\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int pixelIndex) {\nivec2 texSize = textureSize(tex, 0);\nreturn texelFetch(tex, ivec2(pixelIndex % texSize.x, pixelIndex / texSize.x), 0);\n}\n#else\nvec4 fetchVec3ArrayFromTexture(sampler2D tex, int elementIndex) {\nint pixelIndex = elementIndex * 4;\nvec2 location = getPixelLocation(cc_displacementTextureInfo.xy, pixelIndex);\nvec2 x = getPixelCoordFromLocation(location + vec2(0.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 y = getPixelCoordFromLocation(location + vec2(1.0, 0.0), cc_displacementTextureInfo.xy);\nvec2 z = getPixelCoordFromLocation(location + vec2(2.0, 0.0), cc_displacementTextureInfo.xy);\nreturn vec4(\ndecode32(texture(tex, x)),\ndecode32(texture(tex, y)),\ndecode32(texture(tex, z)),\n1.0\n);\n}\n#endif\nfloat getDisplacementWeight(int index) {\nint quot = index / 4;\nint remainder = index - quot * 4;\nif (remainder == 0) {\nreturn cc_displacementWeights[quot].x;\n} else if (remainder == 1) {\nreturn cc_displacementWeights[quot].y;\n} else if (remainder == 2) {\nreturn cc_displacementWeights[quot].z;\n} else {\nreturn cc_displacementWeights[quot].w;\n}\n}\nvec3 getVec3DisplacementFromTexture(sampler2D tex, int vertexIndex) {\n#if CC_MORPH_PRECOMPUTED\nreturn fetchVec3ArrayFromTexture(tex, vertexIndex).rgb;\n#else\nvec3 result = vec3(0, 0, 0);\nint nVertices = int(cc_displacementTextureInfo.z);\nfor (int iTarget = 0; iTarget < CC_MORPH_TARGET_COUNT; ++iTarget) {\nresult += (fetchVec3ArrayFromTexture(tex, nVertices * iTarget + vertexIndex).rgb * getDisplacementWeight(iTarget));\n}\nreturn result;\n#endif\n}\n#if CC_MORPH_TARGET_HAS_POSITION\nvec3 getPositionDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_PositionDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nvec3 getNormalDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_NormalDisplacements, vertexId);\n}\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\nvec3 getTangentDisplacement(int vertexId) {\nreturn getVec3DisplacementFromTexture(cc_TangentDisplacements, vertexId);\n}\n#endif\nvoid applyMorph (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nint vertexId = getVertexId();\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_NORMAL\nnormal.xyz = normal.xyz + getNormalDisplacement(vertexId);\n#endif\n#if CC_MORPH_TARGET_HAS_TANGENT\ntangent.xyz = tangent.xyz + getTangentDisplacement(vertexId);\n#endif\n}\nvoid applyMorph (inout vec4 position) {\n#if CC_MORPH_TARGET_HAS_POSITION\nposition.xyz = position.xyz + getPositionDisplacement(getVertexId());\n#endif\n}\n#endif\n#if CC_USE_SKINNING\n#if CC_USE_BAKED_ANIMATION\nlayout(set = 2, binding = 3) uniform CCSkinningTexture {\nhighp vec4 cc_jointTextureInfo;\n};\nlayout(set = 2, binding = 2) uniform CCSkinningAnimation {\nhighp vec4 cc_jointAnimInfo;\n};\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_jointTexture;\nvoid CCGetJointTextureCoords(float pixelsPerJoint, float jointIdx, out highp float x, out highp float y, out highp float invSize)\n{\n#if USE_INSTANCING\nhighp float temp = pixelsPerJoint * (a_jointAnimInfo.x * a_jointAnimInfo.y + jointIdx) + a_jointAnimInfo.z;\n#else\nhighp float temp = pixelsPerJoint * (cc_jointAnimInfo.x * cc_jointTextureInfo.y + jointIdx) + cc_jointTextureInfo.z;\n#endif\ninvSize = cc_jointTextureInfo.w;\nhighp float tempY = floor(temp * invSize);\nx = floor(temp - tempY * cc_jointTextureInfo.x);\ny = (tempY + 0.5) * invSize;\n}\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\nlayout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint;\n#else\nlayout(set = 2, binding = 3) uniform CCSkinning {\nhighp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3];\n};\n#endif\n#endif\n#if CC_USE_BAKED_ANIMATION\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(3.0, i, x, y, invSize);\nvec4 v1 = texture(cc_jointTexture, vec2((x + 0.5) * invSize, y));\nvec4 v2 = texture(cc_jointTexture, vec2((x + 1.5) * invSize, y));\nvec4 v3 = texture(cc_jointTexture, vec2((x + 2.5) * invSize, y));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nhighp float x, y, invSize;\nCCGetJointTextureCoords(12.0, i, x, y, invSize);\nvec4 v1 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 0.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 1.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 2.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 3.5) * invSize, y)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 4.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 5.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 6.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 7.5) * invSize, y)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_jointTexture, vec2((x + 8.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 9.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 10.5) * invSize, y))),\ndecode32(texture(cc_jointTexture, vec2((x + 11.5) * invSize, y)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\n#if CC_USE_REAL_TIME_JOINT_TEXTURE\n#if CC_DEVICE_SUPPORT_FLOAT_TEXTURE\nmat4 getJointMatrix (float i) {\nfloat x = i;\nvec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0));\nvec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0));\nvec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0));\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#else\nmat4 getJointMatrix (float i) {\nfloat x = 4.0 * i;\nvec4 v1 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0)))\n);\nvec4 v2 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0)))\n);\nvec4 v3 = vec4(\ndecode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))),\ndecode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0)))\n);\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#else\nmat4 getJointMatrix (float i) {\nint idx = int(i);\nvec4 v1 = cc_joints[idx * 3];\nvec4 v2 = cc_joints[idx * 3 + 1];\nvec4 v3 = cc_joints[idx * 3 + 2];\nreturn mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0));\n}\n#endif\n#endif\nmat4 skinMatrix () {\nvec4 joints = vec4(a_joints);\nreturn getJointMatrix(joints.x) * a_weights.x\n+ getJointMatrix(joints.y) * a_weights.y\n+ getJointMatrix(joints.z) * a_weights.z\n+ getJointMatrix(joints.w) * a_weights.w;\n}\nvoid CCSkin (inout vec4 position) {\nmat4 m = skinMatrix();\nposition = m * position;\n}\nvoid CCSkin (inout vec4 position, inout vec3 normal, inout vec4 tangent) {\nmat4 m = skinMatrix();\nposition = m * position;\nnormal = (m * vec4(normal, 0.0)).xyz;\ntangent.xyz = (m * vec4(tangent.xyz, 0.0)).xyz;\n}\n#endif\nvoid CCVertInput(inout StandardVertInput In)\n{\nIn.position = vec4(a_position, 1.0);\nIn.normal = a_normal;\nIn.tangent = a_tangent;\n#if CC_USE_MORPH\napplyMorph(In.position, In.normal, In.tangent);\n#endif\n#if CC_USE_SKINNING\nCCSkin(In.position, In.normal, In.tangent);\n#endif\n}\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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(location = 0) out vec2 v_uv;\nvoid main () {\nStandardVertInput In;\nCCVertInput(In);\nIn.position.xy = cc_cameraPos.w == 0.0 ? vec2(In.position.xy.x, -In.position.xy.y) : In.position.xy;\ngl_Position = In.position;\ngl_Position.y = gl_Position.y;\nv_uv = a_texCoord;\n}", "frag": "\nprecision highp float;\nlayout(set = 0, binding = 0) uniform CCGlobal {\nhighp vec4 cc_time;\nmediump vec4 cc_screenSize;\nmediump vec4 cc_nativeSize;\nmediump vec4 cc_debug_view_mode;\nmediump vec4 cc_debug_view_composite_pack_1;\nmediump vec4 cc_debug_view_composite_pack_2;\nmediump vec4 cc_debug_view_composite_pack_3;\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_surfaceTransform;\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};\n#if ANTIALIAS_TYPE == 1\nvec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution,\nvec2 v_rgbNW, vec2 v_rgbNE,\nvec2 v_rgbSW, vec2 v_rgbSE,\nvec2 v_rgbM) {\nvec4 color;\nmediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);\nvec3 rgbNW = texture(tex, v_rgbNW).xyz;\nvec3 rgbNE = texture(tex, v_rgbNE).xyz;\nvec3 rgbSW = texture(tex, v_rgbSW).xyz;\nvec3 rgbSE = texture(tex, v_rgbSE).xyz;\nvec4 texColor = texture(tex, v_rgbM);\nvec3 rgbM = texColor.xyz;\nvec3 luma = vec3(0.299, 0.587, 0.114);\nfloat lumaNW = dot(rgbNW, luma);\nfloat lumaNE = dot(rgbNE, luma);\nfloat lumaSW = dot(rgbSW, luma);\nfloat lumaSE = dot(rgbSE, luma);\nfloat lumaM = dot(rgbM, luma);\nfloat lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\nfloat lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\nmediump vec2 dir;\ndir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\ndir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\nfloat dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\n(0.25 * (1.0 / 8.0)), (1.0/ 128.0));\nfloat rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\ndir = min(vec2(8.0, 8.0),\nmax(vec2(-8.0, -8.0),\ndir * rcpDirMin)) * inverseVP;\nvec3 rgbA = 0.5 * (\ntexture(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz +\ntexture(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz);\nvec3 rgbB = rgbA * 0.5 + 0.25 * (\ntexture(tex, fragCoord * inverseVP + dir * -0.5).xyz +\ntexture(tex, fragCoord * inverseVP + dir * 0.5).xyz);\nfloat lumaB = dot(rgbB, luma);\nif ((lumaB < lumaMin) || (lumaB > lumaMax))\ncolor = vec4(rgbA, texColor.a);\nelse\ncolor = vec4(rgbB, texColor.a);\nreturn color;\n}\n#endif\nlayout(location = 0) in vec2 v_uv;\nlayout(set = 1, binding = 0) uniform sampler2D outputResultMap;\nlayout(location = 0) out vec4 fragColor;\nvoid texcoords(vec2 fragCoord, vec2 resolution,\nout vec2 v_rgbNW, out vec2 v_rgbNE,\nout vec2 v_rgbSW, out vec2 v_rgbSE,\nout vec2 v_rgbM) {\nvec2 inverseVP = 1.0 / resolution.xy;\nv_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP;\nv_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP;\nv_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP;\nv_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP;\nv_rgbM = vec2(fragCoord * inverseVP);\n}\nvoid main () {\nmediump vec2 v_rgbNW;\nmediump vec2 v_rgbNE;\nmediump vec2 v_rgbSW;\nmediump vec2 v_rgbSE;\nmediump vec2 v_rgbM;\n#if ANTIALIAS_TYPE == 1\nvec2 resolution = cc_screenSize.xy;\nvec2 fragCoord = v_uv * resolution;\ntexcoords(fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\nfragColor = fxaa(outputResultMap, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM);\n#else\nfragColor = texture(outputResultMap, v_uv);\n#endif\n}", } ], diff --git a/cocos/core/game.ts b/cocos/core/game.ts index ea4562c0ba4..9857ae2ca20 100644 --- a/cocos/core/game.ts +++ b/cocos/core/game.ts @@ -37,7 +37,7 @@ import { macro } from './platform/macro'; import type { ICustomJointTextureLayout } from '../3d/skeletal-animation/skeletal-animation-utils'; import { legacyCC, VERSION } from './global-exports'; import { IPhysicsConfig } from '../physics/framework/physics-config'; -import { bindingMappingInfo } from './pipeline/define'; +import { bindingMappingInfo, localDescriptorSetLayout_ResizeMaxJoints } from './pipeline/define'; import { SplashScreen } from './splash-screen'; import { RenderPipeline } from './pipeline/render-pipeline'; import { Node } from './scene-graph/node'; @@ -751,6 +751,8 @@ export class Game extends EventTarget { private _initEngine () { this._initDevice(); + //set max joints after device initialize. + this._resizeMaxJointForDS(); const director = legacyCC.director; return Promise.resolve(director._init()).then(() => { legacyCC.view.init(); @@ -1055,6 +1057,12 @@ export class Game extends EventTarget { this.emit(event); } } + + private _resizeMaxJointForDS () { + let maxJoints = Math.floor((this._gfxDevice!.capabilities.maxVertexUniformVectors - 38) / 3); + maxJoints = maxJoints < 256 ? maxJoints : 256; + localDescriptorSetLayout_ResizeMaxJoints(maxJoints); + } } export declare namespace Game { diff --git a/cocos/core/geometry/spline.ts b/cocos/core/geometry/spline.ts index 6a3e2985f71..08024265416 100644 --- a/cocos/core/geometry/spline.ts +++ b/cocos/core/geometry/spline.ts @@ -23,11 +23,6 @@ THE SOFTWARE. */ -/** - * @packageDocumentation - * @module geometry - */ - import { assertIsTrue } from '../data/utils/asserts'; import { clamp, Vec3 } from '../math'; import { warnID } from '../platform/debug'; @@ -44,7 +39,7 @@ export enum SplineMode { * Piecewise Bezier curve: * Every four knots form a curve. Total knots number must be a multiple of 4. * Each curve passes only the first and fourth knots, and does not pass through the middle two control knots. - * + * * If you need a whole continuous curve: * (1) Suppose the four knots of the previous curve are A, B, C, D * (2) The four knots of the next curve must be D, E, F, G @@ -58,7 +53,7 @@ export enum SplineMode { * The whole curve passes through all knots. */ CATMULL_ROM = 2 -}; +} const SPLINE_WHOLE_INDEX = 0xffffffff; @@ -79,7 +74,7 @@ export class Spline { private _mode: SplineMode = SplineMode.CATMULL_ROM; private _knots: Vec3[] = []; - private constructor(mode: SplineMode = SplineMode.CATMULL_ROM, knots: Readonly = []) { + private constructor (mode: SplineMode = SplineMode.CATMULL_ROM, knots: Readonly = []) { this._type = enums.SHAPE_SPLINE; this._mode = mode; @@ -130,48 +125,48 @@ export class Spline { } } - public clearKnots() { + public clearKnots () { this._knots.length = 0; } - public getKnotCount() { - return this._knots.length; + public getKnotCount () { + return this._knots.length; } - public addKnot(knot: Vec3) { - this._knots.push(new Vec3(knot)); + public addKnot (knot: Vec3) { + this._knots.push(new Vec3(knot)); } - public insertKnot(index: number, knot: Vec3) { + public insertKnot (index: number, knot: Vec3) { const item = new Vec3(knot); if (index >= this._knots.length) { this._knots.push(item); return; } - + this._knots.splice(index, 0, item); } - public removeKnot(index: number) { - assertIsTrue(index >= 0 && index < this._knots.length, "Spline: invalid index"); + public removeKnot (index: number) { + assertIsTrue(index >= 0 && index < this._knots.length, 'Spline: invalid index'); this._knots.splice(index, 1); } - public setKnot(index: number, knot: Vec3) { - assertIsTrue(index >= 0 && index < this._knots.length, "Spline: invalid index"); + public setKnot (index: number, knot: Vec3) { + assertIsTrue(index >= 0 && index < this._knots.length, 'Spline: invalid index'); this._knots[index].set(knot); } - public getKnot(index: number): Readonly { - assertIsTrue(index >= 0 && index < this._knots.length, "Spline: invalid index"); + public getKnot (index: number): Readonly { + assertIsTrue(index >= 0 && index < this._knots.length, 'Spline: invalid index'); return this._knots[index]; } // get a point at t with repect to the `index` segment of curve or the whole curve. - public getPoint(t: number, index: number = SPLINE_WHOLE_INDEX) { + public getPoint (t: number, index: number = SPLINE_WHOLE_INDEX) { t = clamp(t, 0.0, 1.0); const segments = this.getSegments(); @@ -191,68 +186,68 @@ export class Spline { } switch (this._mode) { - case SplineMode.LINEAR: - return Spline.calcLinear(this._knots[index], this._knots[index + 1], t); - case SplineMode.BEZIER: - return Spline.calcBezier(this._knots[index * 4], this._knots[index * 4 + 1], this._knots[index * 4 + 2], this._knots[index * 4 + 3], t); - case SplineMode.CATMULL_ROM: { - const v0 = index > 0 ? this._knots[index - 1] : this._knots[index]; - const v3 = index + 2 < this._knots.length ? this._knots[index + 2] : this._knots[index + 1]; - return Spline.calcCatmullRom(v0, this._knots[index], this._knots[index + 1], v3, t); - } - default: - return new Vec3(0.0, 0.0, 0.0); + case SplineMode.LINEAR: + return Spline.calcLinear(this._knots[index], this._knots[index + 1], t); + case SplineMode.BEZIER: + return Spline.calcBezier(this._knots[index * 4], this._knots[index * 4 + 1], this._knots[index * 4 + 2], this._knots[index * 4 + 3], t); + case SplineMode.CATMULL_ROM: { + const v0 = index > 0 ? this._knots[index - 1] : this._knots[index]; + const v3 = index + 2 < this._knots.length ? this._knots[index + 2] : this._knots[index + 1]; + return Spline.calcCatmullRom(v0, this._knots[index], this._knots[index + 1], v3, t); + } + default: + return new Vec3(0.0, 0.0, 0.0); } } // get num points from 0 to 1 uniformly with repect to the `index` segment of curve or the whole curve - public getPoints(num: number, index: number = SPLINE_WHOLE_INDEX): Vec3[] { + public getPoints (num: number, index: number = SPLINE_WHOLE_INDEX): Vec3[] { if (num == 0) { return []; } - + if (num == 1) { const point = this.getPoint(0.0, index); return [point]; } - - let points: Vec3[] = []; + + const points: Vec3[] = []; const deltaT = 1.0 / (num - 1.0); - + for (let i = 0; i < num; i++) { const t = i * deltaT; const point = this.getPoint(t, index); - + points.push(point); } - + return points; } - private getSegments() { + private getSegments () { const count = this._knots.length; switch (this._mode) { - case SplineMode.LINEAR: - case SplineMode.CATMULL_ROM: - if (count < 2) { - warnID(14300); - return 0; - } - - return count - 1; - case SplineMode.BEZIER: - if (count < 4 || count % 4 != 0) { - warnID(14301); - return 0; - } - - return count / 4; - default: - assertIsTrue(false, "Spline error: invalid mode"); + case SplineMode.LINEAR: + case SplineMode.CATMULL_ROM: + if (count < 2) { + warnID(14300); + return 0; + } + + return count - 1; + case SplineMode.BEZIER: + if (count < 4 || count % 4 != 0) { + warnID(14301); + return 0; + } + + return count / 4; + default: + assertIsTrue(false, 'Spline error: invalid mode'); } } - private static calcLinear(v0: Vec3, v1: Vec3, t: number) { + private static calcLinear (v0: Vec3, v1: Vec3, t: number) { const result = new Vec3(); Vec3.multiplyScalar(_v0, v0, (1.0 - t)); Vec3.multiplyScalar(_v1, v1, t); @@ -261,7 +256,7 @@ export class Spline { return result; } - private static calcBezier(v0: Vec3, v1: Vec3, v2: Vec3, v3: Vec3, t: number) { + private static calcBezier (v0: Vec3, v1: Vec3, v2: Vec3, v3: Vec3, t: number) { const result = new Vec3(); const s = 1.0 - t; Vec3.multiplyScalar(_v0, v0, s * s * s); @@ -274,7 +269,7 @@ export class Spline { return result; } - private static calcCatmullRom(v0: Vec3, v1: Vec3, v2: Vec3, v3: Vec3, t: number) { + private static calcCatmullRom (v0: Vec3, v1: Vec3, v2: Vec3, v3: Vec3, t: number) { const result = new Vec3(); const t2 = t * t; const t3 = t2 * t; diff --git a/cocos/core/pipeline/custom/index.jsb.ts b/cocos/core/pipeline/custom/index.jsb.ts index 7bbcc8fd469..7d82f809fc8 100644 --- a/cocos/core/pipeline/custom/index.jsb.ts +++ b/cocos/core/pipeline/custom/index.jsb.ts @@ -23,11 +23,6 @@ THE SOFTWARE. */ -/** - * @packageDocumentation - * @module custom-pipeline - */ - declare const render: any; import { Pipeline } from './pipeline'; diff --git a/cocos/core/pipeline/custom/index.ts b/cocos/core/pipeline/custom/index.ts index 66dd0e35fde..9a11f74bace 100644 --- a/cocos/core/pipeline/custom/index.ts +++ b/cocos/core/pipeline/custom/index.ts @@ -23,11 +23,6 @@ THE SOFTWARE. */ -/** - * @packageDocumentation - * @module custom-pipeline - */ - import { Pipeline } from './pipeline'; import { WebPipeline } from './web-pipeline'; import { rebuildLayoutGraph } from './effect'; diff --git a/cocos/core/pipeline/define.ts b/cocos/core/pipeline/define.ts index 762bd2d7353..b38c00d41e0 100644 --- a/cocos/core/pipeline/define.ts +++ b/cocos/core/pipeline/define.ts @@ -479,19 +479,39 @@ localDescriptorSetLayout.bindings[UBOSkinningAnimation.BINDING] = UBOSkinningAni export const INST_JOINT_ANIM_INFO = 'a_jointAnimInfo'; export class UBOSkinning { - public static readonly JOINTS_OFFSET = 0; - public static readonly COUNT = UBOSkinning.JOINTS_OFFSET + JOINT_UNIFORM_CAPACITY * 12; - public static readonly SIZE = UBOSkinning.COUNT * 4; + private static _jointUniformCapacity = 0; + public static get JOINT_UNIFORM_CAPACITY () { return UBOSkinning._jointUniformCapacity; } + private static _count = 0; + public static get COUNT () { return UBOSkinning._count; } + private static _size = 0; + public static get SIZE () { return UBOSkinning._size; } public static readonly NAME = 'CCSkinning'; public static readonly BINDING = ModelLocalBindings.UBO_SKINNING_TEXTURE; public static readonly DESCRIPTOR = new DescriptorSetLayoutBinding(UBOSkinning.BINDING, DescriptorType.UNIFORM_BUFFER, 1, ShaderStageFlagBit.VERTEX); public static readonly LAYOUT = new UniformBlock(SetIndex.LOCAL, UBOSkinning.BINDING, UBOSkinning.NAME, [ - new Uniform('cc_joints', Type.FLOAT4, JOINT_UNIFORM_CAPACITY * 3), + new Uniform('cc_joints', Type.FLOAT4, 1), ], 1); + + /** + * @internal This method only used init UBOSkinning configure. + */ + public static initLayout (capacity: number) { + UBOSkinning._jointUniformCapacity = capacity; + UBOSkinning._count = capacity * 12; + UBOSkinning._size = UBOSkinning._count * 4; + UBOSkinning.LAYOUT.members[0].count = capacity * 3; + } +} + +/** + * @internal This method only used to init localDescriptorSetLayout.layouts[UBOSkinning.NAME] +*/ +export function localDescriptorSetLayout_ResizeMaxJoints (maxCount: number) { + UBOSkinning.initLayout(maxCount); + localDescriptorSetLayout.layouts[UBOSkinning.NAME] = UBOSkinning.LAYOUT; + localDescriptorSetLayout.bindings[UBOSkinning.BINDING] = UBOSkinning.DESCRIPTOR; } -localDescriptorSetLayout.layouts[UBOSkinning.NAME] = UBOSkinning.LAYOUT; -localDescriptorSetLayout.bindings[UBOSkinning.BINDING] = UBOSkinning.DESCRIPTOR; /** * @en The uniform buffer object for morph setting @@ -540,6 +560,17 @@ const UNIFORM_JOINT_TEXTURE_LAYOUT = new UniformSamplerTexture(SetIndex.LOCAL, U localDescriptorSetLayout.layouts[UNIFORM_JOINT_TEXTURE_NAME] = UNIFORM_JOINT_TEXTURE_LAYOUT; localDescriptorSetLayout.bindings[UNIFORM_JOINT_TEXTURE_BINDING] = UNIFORM_JOINT_TEXTURE_DESCRIPTOR; +/** + * @en The sampler for real-time joint texture + * @zh 实时骨骼纹理采样器。 + */ +const UNIFORM_REALTIME_JOINT_TEXTURE_NAME = 'cc_realtimeJoint'; +export const UNIFORM_REALTIME_JOINT_TEXTURE_BINDING = ModelLocalBindings.SAMPLER_JOINTS; +const UNIFORM_REALTIME_JOINT_TEXTURE_DESCRIPTOR = new DescriptorSetLayoutBinding(UNIFORM_REALTIME_JOINT_TEXTURE_BINDING, DescriptorType.SAMPLER_TEXTURE, 1, ShaderStageFlagBit.VERTEX); +const UNIFORM_REALTIME_JOINT_TEXTURE_LAYOUT = new UniformSamplerTexture(SetIndex.LOCAL, UNIFORM_REALTIME_JOINT_TEXTURE_BINDING, UNIFORM_REALTIME_JOINT_TEXTURE_NAME, Type.SAMPLER2D, 1); +localDescriptorSetLayout.layouts[UNIFORM_REALTIME_JOINT_TEXTURE_NAME] = UNIFORM_REALTIME_JOINT_TEXTURE_LAYOUT; +localDescriptorSetLayout.bindings[UNIFORM_REALTIME_JOINT_TEXTURE_BINDING] = UNIFORM_REALTIME_JOINT_TEXTURE_DESCRIPTOR; + /** * @en The sampler for morph texture of position * @zh 位置形变纹理采样器。 diff --git a/cocos/core/pipeline/geometry-renderer.ts b/cocos/core/pipeline/geometry-renderer.ts index f4be270a2da..b8191eb2e79 100644 --- a/cocos/core/pipeline/geometry-renderer.ts +++ b/cocos/core/pipeline/geometry-renderer.ts @@ -23,10 +23,6 @@ THE SOFTWARE. */ -/** - * @packageDocumentation - * @module geometry-renderer - */ import { AABB } from '../geometry/aabb'; import { Spline } from '../geometry/spline'; import { Color } from '../math/color'; diff --git a/cocos/core/pipeline/render-pipeline.ts b/cocos/core/pipeline/render-pipeline.ts index 3895e49795e..95d54617802 100644 --- a/cocos/core/pipeline/render-pipeline.ts +++ b/cocos/core/pipeline/render-pipeline.ts @@ -47,6 +47,7 @@ import { IPipelineEvent, PipelineEventProcessor, PipelineEventType } from './pip import { decideProfilerCamera } from './pipeline-funcs'; import { OS } from '../../../pal/system-info/enum-type'; import { macro } from '../platform/macro'; +import { UBOSkinning } from './define'; import { PipelineRuntime } from './custom/pipeline'; /** @@ -686,6 +687,10 @@ export abstract class RenderPipeline extends Asset implements IPipelineEvent, Pi str += `#define CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT ${this.device.hasFeature(Feature.INPUT_ATTACHMENT_BENEFIT) ? 1 : 0}\n`; str += `#define CC_PLATFORM_ANDROID_AND_WEBGL ${systemInfo.os === OS.ANDROID && systemInfo.isBrowser ? 1 : 0}\n`; str += `#define CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES ${macro.ENABLE_WEBGL_HIGHP_STRUCT_VALUES ? 1 : 0}\n`; + + const jointUniformCapacity = UBOSkinning.JOINT_UNIFORM_CAPACITY; + str += `#define CC_JOINT_UNIFORM_CAPACITY ${jointUniformCapacity}\n`; + this._constantMacros = str; } diff --git a/cocos/core/platform/sys.ts b/cocos/core/platform/sys.ts index 970b40845af..a8802e4a384 100644 --- a/cocos/core/platform/sys.ts +++ b/cocos/core/platform/sys.ts @@ -29,9 +29,9 @@ import { screenAdapter } from 'pal/screen-adapter'; import { WECHAT } from 'internal:constants'; import { legacyCC } from '../global-exports'; import { Rect } from '../math/rect'; +import { Vec2 } from '../math/vec2'; import { warnID, log } from './debug'; import { NetworkType, Language, OS, Platform, BrowserType, Feature } from '../../../pal/system-info/enum-type'; -import { Vec2 } from '../math'; import { screen } from './screen'; export declare namespace sys { diff --git a/cocos/particle/animator/limit-velocity-overtime.ts b/cocos/particle/animator/limit-velocity-overtime.ts index 75f8fe3c639..9e4f572a7d3 100644 --- a/cocos/particle/animator/limit-velocity-overtime.ts +++ b/cocos/particle/animator/limit-velocity-overtime.ts @@ -23,7 +23,7 @@ THE SOFTWARE. */ -import { ccclass, tooltip, displayOrder, range, type, serializable } from 'cc.decorator'; +import { ccclass, tooltip, displayOrder, range, type, serializable, visible } from 'cc.decorator'; import { lerp, pseudoRandom, Vec3, Mat4, Quat } from '../../core/math'; import { Space, ModuleRandSeed } from '../enum'; import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; @@ -62,6 +62,9 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { @range([-1, 1]) @displayOrder(4) @tooltip('i18n:limitVelocityOvertimeModule.limitX') + @visible(function (this: LimitVelocityOvertimeModule): boolean { + return this.separateAxes; + }) public limitX = new CurveRange(); /** @@ -72,6 +75,9 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { @range([-1, 1]) @displayOrder(5) @tooltip('i18n:limitVelocityOvertimeModule.limitY') + @visible(function (this: LimitVelocityOvertimeModule): boolean { + return this.separateAxes; + }) public limitY = new CurveRange(); /** @@ -82,6 +88,9 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { @range([-1, 1]) @displayOrder(6) @tooltip('i18n:limitVelocityOvertimeModule.limitZ') + @visible(function (this: LimitVelocityOvertimeModule): boolean { + return this.separateAxes; + }) public limitZ = new CurveRange(); /** @@ -92,6 +101,9 @@ export default class LimitVelocityOvertimeModule extends ParticleModuleBase { @range([-1, 1]) @displayOrder(3) @tooltip('i18n:limitVelocityOvertimeModule.limit') + @visible(function (this: LimitVelocityOvertimeModule): boolean { + return !this.separateAxes; + }) public limit = new CurveRange(); /** diff --git a/cocos/particle/animator/noise-module.ts b/cocos/particle/animator/noise-module.ts new file mode 100644 index 00000000000..9693bdcb4da --- /dev/null +++ b/cocos/particle/animator/noise-module.ts @@ -0,0 +1,262 @@ +/* + Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated engine source code (the "Software"), a limited, + worldwide, royalty-free, non-assignable, revocable and non-exclusive license + to use Cocos Creator solely to develop games on your target platforms. You shall + not use Cocos Creator software for developing other software or tools that's + used for developing games. You are not granted to publish, distribute, + sublicense, and/or sell copies of Cocos Creator. + + The software or tools in this License Agreement are licensed, not sold. + Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +import { ccclass, displayOrder, type, serializable } from 'cc.decorator'; +import { range, rangeStep, slide, visible } from '../../core/data/decorators/editable'; +import { Vec3 } from '../../core/math'; +import { ParticleNoise } from '../noise'; +import { Particle, PARTICLE_MODULE_NAME, ParticleModuleBase } from '../particle'; + +@ccclass('cc.NoiseModule') +export class NoiseModule extends ParticleModuleBase { + @serializable + _enable = false; + /** + * @zh 是否启用。 + */ + @displayOrder(0) + public get enable () { + return this._enable; + } + + public set enable (val) { + if (this._enable === val) return; + this._enable = val; + if (!this.target) return; + this.target.enableModule(this.name, val, this); + } + + @type(Number) + @range([0, 100]) + @displayOrder(16) + @slide + get strengthX () { + return this._strengthX; + } + set strengthX (value: number) { + this._strengthX = value; + } + @serializable + private _strengthX = 0; + + @type(Number) + @range([0, 100]) + @displayOrder(16) + @slide + get strengthY () { + return this._strengthY; + } + set strengthY (value: number) { + this._strengthY = value; + } + @serializable + private _strengthY = 0; + + @type(Number) + @range([0, 100]) + @displayOrder(16) + @slide + get strengthZ () { + return this._strengthZ; + } + set strengthZ (value: number) { + this._strengthZ = value; + } + @serializable + private _strengthZ = 0; + + @type(Number) + @range([0, 100]) + @slide + @displayOrder(16) + get noiseSpeedX () { + return this._noiseSpeedX; + } + set noiseSpeedX (value: number) { + this._noiseSpeedX = value; + } + @serializable + private _noiseSpeedX = 0; + + @type(Number) + @range([0, 100]) + @displayOrder(16) + @slide + get noiseSpeedY () { + return this._noiseSpeedY; + } + set noiseSpeedY (value: number) { + this._noiseSpeedY = value; + } + @serializable + private _noiseSpeedY = 0; + + @type(Number) + @range([0, 100]) + @displayOrder(16) + @slide + get noiseSpeedZ () { + return this._noiseSpeedZ; + } + set noiseSpeedZ (value: number) { + this._noiseSpeedZ = value; + } + @serializable + private _noiseSpeedZ = 0; + + @type(Number) + @range([0, 100]) + @rangeStep(0.1) + @displayOrder(16) + @slide + get noiseFrequency () { + return this._noiseFrequency; + } + set noiseFrequency (value: number) { + this._noiseFrequency = value; + } + @serializable + private _noiseFrequency = 0; + + @visible(false) + @type(Number) + @range([0, 1]) + @rangeStep(0.1) + @displayOrder(16) + @slide + get remapX () { + return this._remapX; + } + set remapX (value: number) { + this._remapX = value; + } + @serializable + private _remapX = 0; + + @visible(false) + @type(Number) + @range([0, 1]) + @rangeStep(0.1) + @displayOrder(16) + @slide + get remapY () { + return this._remapY; + } + set remapY (value: number) { + this._remapY = value; + } + @serializable + private _remapY = 0; + + @visible(false) + @type(Number) + @range([0, 1]) + @rangeStep(0.1) + @displayOrder(16) + @slide + get remapZ () { + return this._remapZ; + } + set remapZ (value: number) { + this._remapZ = value; + } + @serializable + private _remapZ = 0; + + @type(Number) + @range([1, 4]) + @rangeStep(1) + @displayOrder(16) + @slide + get octaves () { + return this._octaves; + } + set octaves (value: number) { + this._octaves = value; + } + @serializable + private _octaves = 1; + + // eslint-disable-next-line func-names + @visible(function (this: NoiseModule) { return this._octaves > 1; }) + @type(Number) + @range([0, 1]) + @rangeStep(0.1) + @displayOrder(16) + get octaveMultiplier () { + return this._octaveMultiplier; + } + set octaveMultiplier (value: number) { + this._octaveMultiplier = value; + } + @serializable + private _octaveMultiplier = 1; + + // eslint-disable-next-line func-names + @visible(function (this: NoiseModule) { return this._octaves > 1; }) + @type(Number) + @range([1, 4]) + @rangeStep(0.1) + @displayOrder(16) + get octaveScale () { + return this._octaveScale; + } + set octaveScale (value: number) { + this._octaveScale = value; + } + @serializable + private _octaveScale = 1; + + public name = PARTICLE_MODULE_NAME.NOISE; + + private noise: ParticleNoise = new ParticleNoise(); + + public animate (particle: Particle, dt: number) { + this.noise.setTime(particle.particleSystem.time); + this.noise.setSpeed(this.noiseSpeedX, this.noiseSpeedY, this.noiseSpeedZ); + this.noise.setFrequency(this.noiseFrequency); + this.noise.setAbs(this.remapX, this.remapY, this.remapZ); + this.noise.setAmplititude(this.strengthX, this.strengthY, this.strengthZ); + this.noise.setOctaves(this.octaves, this.octaveMultiplier, this.octaveScale); + this.noise.setSamplePoint(particle.position); + this.noise.getNoiseParticle(); + + const noisePosition: Vec3 = this.noise.getResult(); + noisePosition.multiply3f(Math.random(), Math.random(), Math.random()); + Vec3.add(particle.position, particle.position, noisePosition.multiplyScalar(dt)); + } + + public getNoisePreview (out: number[], ps, width: number, height: number) { + this.noise.setTime(ps.time); + this.noise.setSpeed(this.noiseSpeedX, this.noiseSpeedY, this.noiseSpeedZ); + this.noise.setFrequency(this.noiseFrequency); + this.noise.setAbs(this.remapX, this.remapY, this.remapZ); + this.noise.setAmplititude(this.strengthX, this.strengthY, this.strengthZ); + this.noise.setOctaves(this.octaves, this.octaveMultiplier, this.octaveScale); + this.noise.getNoiseParticle(); + + this.noise.getPreview(out, width, height); + } +} diff --git a/cocos/particle/animator/rotation-overtime.ts b/cocos/particle/animator/rotation-overtime.ts index a827935f309..413135fa7b9 100644 --- a/cocos/particle/animator/rotation-overtime.ts +++ b/cocos/particle/animator/rotation-overtime.ts @@ -24,7 +24,7 @@ THE SOFTWARE. */ -import { ccclass, tooltip, displayOrder, range, type, radian, serializable } from 'cc.decorator'; +import { ccclass, tooltip, displayOrder, range, type, radian, serializable, visible } from 'cc.decorator'; import { Mat4, pseudoRandom, Quat, Vec4, Vec3 } from '../../core/math'; import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; import CurveRange from './curve-range'; @@ -76,6 +76,7 @@ export default class RotationOvertimeModule extends ParticleModuleBase { @radian @displayOrder(2) @tooltip('i18n:rotationOvertimeModule.x') + @visible(function (this: RotationOvertimeModule): boolean { return this.separateAxes; }) public x = new CurveRange(); /** @@ -87,6 +88,7 @@ export default class RotationOvertimeModule extends ParticleModuleBase { @radian @displayOrder(3) @tooltip('i18n:rotationOvertimeModule.y') + @visible(function (this: RotationOvertimeModule): boolean { return this.separateAxes; }) public y = new CurveRange(); /** diff --git a/cocos/particle/animator/size-overtime.ts b/cocos/particle/animator/size-overtime.ts index 5547c1c84fc..78cd3710294 100644 --- a/cocos/particle/animator/size-overtime.ts +++ b/cocos/particle/animator/size-overtime.ts @@ -23,7 +23,7 @@ THE SOFTWARE. */ -import { ccclass, tooltip, displayOrder, type, serializable, range } from 'cc.decorator'; +import { ccclass, tooltip, displayOrder, type, serializable, range, visible } from 'cc.decorator'; import { pseudoRandom, Vec3 } from '../../core/math'; import { Particle, ParticleModuleBase, PARTICLE_MODULE_NAME } from '../particle'; import CurveRange from './curve-range'; @@ -66,6 +66,7 @@ export default class SizeOvertimeModule extends ParticleModuleBase { @range([0, 1]) @displayOrder(2) @tooltip('i18n:sizeOvertimeModule.size') + @visible(function (this: SizeOvertimeModule): boolean { return !this.separateAxes; }) public size = new CurveRange(); /** @@ -76,6 +77,7 @@ export default class SizeOvertimeModule extends ParticleModuleBase { @range([0, 1]) @displayOrder(3) @tooltip('i18n:sizeOvertimeModule.x') + @visible(function (this: SizeOvertimeModule): boolean { return this.separateAxes; }) public x = new CurveRange(); /** @@ -86,6 +88,7 @@ export default class SizeOvertimeModule extends ParticleModuleBase { @range([0, 1]) @displayOrder(4) @tooltip('i18n:sizeOvertimeModule.y') + @visible(function (this: SizeOvertimeModule): boolean { return this.separateAxes; }) public y = new CurveRange(); /** @@ -96,6 +99,7 @@ export default class SizeOvertimeModule extends ParticleModuleBase { @range([0, 1]) @displayOrder(5) @tooltip('i18n:sizeOvertimeModule.z') + @visible(function (this: SizeOvertimeModule): boolean { return this.separateAxes; }) public z = new CurveRange(); public name = PARTICLE_MODULE_NAME.SIZE; diff --git a/cocos/particle/emitter/shape-module.ts b/cocos/particle/emitter/shape-module.ts index 0f945430736..54c54f22c4c 100644 --- a/cocos/particle/emitter/shape-module.ts +++ b/cocos/particle/emitter/shape-module.ts @@ -35,6 +35,16 @@ import { ParticleSystem } from '../particle-system'; const _intermediVec = new Vec3(0, 0, 0); const _intermediArr: number[] = []; const _unitBoxExtent = new Vec3(0.5, 0.5, 0.5); +function getShapeTypeEnumName(enumValue: number): keyof typeof ShapeType { + let enumName = ''; + for (const key in ShapeType) { + if (ShapeType[key] === enumValue) { + enumName = key; + break; + } + } + return enumName as keyof typeof ShapeType; +} @ccclass('cc.ShapeModule') export default class ShapeModule { @@ -82,7 +92,12 @@ export default class ShapeModule { */ @displayOrder(6) @tooltip('i18n:shapeModule.arc') - get arc () { + @visible(function (this: ShapeModule) { + const subset: Array = ['Cone', 'Circle']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) + get arc() { return toDegree(this._arc); } @@ -96,7 +111,12 @@ export default class ShapeModule { */ @displayOrder(5) @tooltip('i18n:shapeModule.angle') - get angle () { + @visible(function (this: ShapeModule) { + const subset: Array = ['Cone']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) + get angle() { return Math.round(toDegree(this._angle) * 100) / 100; } @@ -165,6 +185,11 @@ export default class ShapeModule { @serializable @displayOrder(2) @tooltip('i18n:shapeModule.emitFrom') + @visible(function (this: ShapeModule) { + const subset: Array = ['Box', 'Cone', 'Sphere', 'Hemisphere']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) public emitFrom = EmitLocation.Volume; /** @@ -205,6 +230,11 @@ export default class ShapeModule { @serializable @displayOrder(3) @tooltip('i18n:shapeModule.radius') + @visible(function (this: ShapeModule) { + const subset: Array = ['Circle', 'Cone', 'Sphere', 'Hemisphere']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) public radius = 1; /** @@ -216,6 +246,11 @@ export default class ShapeModule { @serializable @displayOrder(4) @tooltip('i18n:shapeModule.radiusThickness') + @visible(function (this: ShapeModule) { + const subset: Array = ['Circle', 'Cone', 'Sphere', 'Hemisphere']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) public radiusThickness = 1; /** @@ -225,6 +260,11 @@ export default class ShapeModule { @serializable @displayOrder(7) @tooltip('i18n:shapeModule.arcMode') + @visible(function (this: ShapeModule) { + const subset: Array = ['Cone', 'Circle']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) public arcMode = ArcMode.Random; /** @@ -234,6 +274,11 @@ export default class ShapeModule { @serializable @displayOrder(9) @tooltip('i18n:shapeModule.arcSpread') + @visible(function (this: ShapeModule) { + const subset: Array = ['Cone', 'Circle']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) public arcSpread = 0; /** @@ -245,6 +290,11 @@ export default class ShapeModule { @serializable @displayOrder(10) @tooltip('i18n:shapeModule.arcSpeed') + @visible(function (this: ShapeModule) { + const subset: Array = ['Cone', 'Circle']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) public arcSpeed = new CurveRange(); /** @@ -254,6 +304,11 @@ export default class ShapeModule { @serializable @displayOrder(11) @tooltip('i18n:shapeModule.length') + @visible(function (this: ShapeModule) { + const subset: Array = ['Cone']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) public length = 5; /** @@ -262,6 +317,11 @@ export default class ShapeModule { @serializable @displayOrder(12) @tooltip('i18n:shapeModule.boxThickness') + @visible(function (this: ShapeModule) { + const subset: Array = ['Box']; + const enumName = getShapeTypeEnumName(this.shapeType); + return subset.includes(enumName); + }) public boxThickness = new Vec3(0, 0, 0); @serializable diff --git a/cocos/particle/models/particle-batch-model.ts b/cocos/particle/models/particle-batch-model.ts index 574b1c897eb..efb11c0c69a 100644 --- a/cocos/particle/models/particle-batch-model.ts +++ b/cocos/particle/models/particle-batch-model.ts @@ -24,10 +24,6 @@ THE SOFTWARE. */ -/** - * @packageDocumentation - * @hidden - */ import { JSB } from 'internal:constants'; import { Mesh } from '../../3d/assets/mesh'; import { AttributeName, BufferUsageBit, FormatInfos, MemoryUsageBit, PrimitiveMode, diff --git a/cocos/particle/noise.ts b/cocos/particle/noise.ts new file mode 100644 index 00000000000..905d1d5c691 --- /dev/null +++ b/cocos/particle/noise.ts @@ -0,0 +1,190 @@ +/* + Copyright (c) 2022 Xiamen Yaji Software Co., Ltd. + + https://www.cocos.com/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated engine source code (the "Software"), a limited, + worldwide, royalty-free, non-assignable, revocable and non-exclusive license + to use Cocos Creator solely to develop games on your target platforms. You shall + not use Cocos Creator software for developing other software or tools that's + used for developing games. You are not granted to publish, distribute, + sublicense, and/or sell copies of Cocos Creator. + + The software or tools in this License Agreement are licensed, not sold. + Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +import { Vec2, Vec3 } from '../core/math'; + +export class ParticleNoise { + private permutation: number[] = [151, 160, 137, 91, 90, 15, + 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, + 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, + 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, + 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, + 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, + 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, + 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, + 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, + 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, + 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, + 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, + 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, + ]; + + constructor (permutation ? : number[]) { + if (permutation) { + this.permutation = permutation; + } + } + + public noise (x: number, y: number, z: number, min = 0, max = 1): number { + const p: number[] = new Array(512); + for (let i = 0; i < 256; i++) { p[256 + i] = p[i] = this.permutation[i]; } + + const X = Math.floor(x) & 255; // FIND UNIT CUBE THAT + const Y = Math.floor(y) & 255; // CONTAINS POINT. + const Z = Math.floor(z) & 255; + x -= Math.floor(x); // FIND RELATIVE X,Y,Z + y -= Math.floor(y); // OF POINT IN CUBE. + z -= Math.floor(z); + const u = this.fade(x); // COMPUTE FADE CURVES + const v = this.fade(y); // FOR EACH OF X,Y,Z. + const w = this.fade(z); + const A = p[X] + Y; + const AA = p[A] + Z; + const AB = p[A + 1] + Z; // HASH COORDINATES OF + const B = p[X + 1] + Y; + const BA = p[B] + Z; + const BB = p[B + 1] + Z; // THE 8 CUBE CORNERS, + + // The perlin noise value 0 -> 1 + const val = this.scale(this.lerp(w, this.lerp(v, this.lerp(u, this.grad(p[AA], x, y, z), // AND ADD + this.grad(p[BA], x - 1, y, z)), // BLENDED + this.lerp(u, this.grad(p[AB], x, y - 1, z), // RESULTS + this.grad(p[BB], x - 1, y - 1, z))), // FROM 8 + this.lerp(v, this.lerp(u, this.grad(p[AA + 1], x, y, z - 1), // CORNERS + this.grad(p[BA + 1], x - 1, y, z - 1)), // OF CUBE + this.lerp(u, this.grad(p[AB + 1], x, y - 1, z - 1), + this.grad(p[BB + 1], x - 1, y - 1, z - 1))))); + + return min + val * (max - min); + } + private fade (t: number): number { + return t * t * t * (t * (t * 6 - 15) + 10); + } + private lerp (t: number, a: number, b: number): number { + return a + t * (b - a); + } + private grad (hash: number, x: number, y: number, z: number): number { + const h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE + const u = h < 8 ? x : y; // INTO 12 this.gradIENT DIRECTIONS. + const v = h < 4 ? y : h === 12 || h === 14 ? x : z; + return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v); + } + private scale (n: number): number { + return (1 + n) / 2; + } + + private accSpeed: Vec3 = new Vec3(); + private noiseSpeed: Vec3 = new Vec3(); + private noiseFrequency = 0.0; + private noiseAbs: Vec3 = new Vec3(); + private noiseAmplitude: Vec3 = new Vec3(); + private octaves: Vec3 = new Vec3(); + private dt = 0.0; + private point: Vec3 = new Vec3(); + private result: Vec3 = new Vec3(); + private mixOut: Vec2 = new Vec2(); + + public setSpeed (x, y, z) { + this.noiseSpeed.set(x, y, z); + } + + public setFrequency (f) { + this.noiseFrequency = f; + } + + public setAbs (x, y, z) { + this.noiseAbs.set(x, y, z); + } + + public setAmplititude (x, y, z) { + this.noiseAmplitude.set(x, y, z); + } + + public setOctaves (x, y, z) { + this.octaves.set(x, y, z); + } + + public setTime (t) { + this.dt = t; + } + + public setSamplePoint (p: Vec3) { + this.point.set(p); + } + + public getResult (): Vec3 { + return this.result; + } + + private getNoise (sx: number, sy: number, sz: number, time: number, offset: Vec3, noiseFrequency: number, octaves: Vec3): number { + let frequency = noiseFrequency; + let sum = 0.0; + sum += this.noise(sx * frequency, sy * frequency, sz * frequency, -1.0, 1.0); + if (octaves.x === 1) { + return sum; + } + + let amplitude = 1.0; + let range = 1.0; + for (let i = 1; i < octaves.x; ++i) { + amplitude *= octaves.y; + frequency *= octaves.z; + range += amplitude; + + sum += this.noise(sx * frequency, sy * frequency, sz * frequency, -1.0, 1.0) * amplitude; + } + return sum / range; + } + + private getNoiseMix (out: Vec2, point: Vec3, time: number, offSpeed: Vec3, noiseFrequency: number, octaves: Vec3) { + out.x = this.getNoise(point.x, point.y, point.z, time, offSpeed, noiseFrequency, octaves); + out.y = this.getNoise(point.y, point.z, point.x, time, offSpeed, noiseFrequency, octaves); + } + + public getNoiseParticle () { + this.accSpeed.set(this.noiseSpeed.x * this.dt, this.noiseSpeed.y * this.dt, this.noiseSpeed.z * this.dt); + + const axisOffset = 1000.0; + // eslint-disable-next-line max-len + const sampX = this.getNoise(this.point.z + this.accSpeed.x, this.point.y, this.point.x, this.dt, this.accSpeed, this.noiseFrequency, this.octaves); + // eslint-disable-next-line max-len + const sampY = this.getNoise(this.point.x + axisOffset, this.point.z + this.accSpeed.y, this.point.y, this.dt, this.accSpeed, this.noiseFrequency, this.octaves); + // eslint-disable-next-line max-len + const sampZ = this.getNoise(this.point.y, this.point.x + axisOffset, this.point.z + this.accSpeed.z, this.dt, this.accSpeed, this.noiseFrequency, this.octaves); + + this.result.set(sampX * this.noiseAmplitude.x, sampY * this.noiseAmplitude.y, sampZ * this.noiseAmplitude.z); + } + + public getPreview (out: number[], width: number, height: number) { + for (let h = 0; h < height; ++h) { + for (let w = 0; w < width; ++w) { + const sampx = (w - width * 0.5) / width + this.noiseSpeed.x * this.dt; + const sampy = (h - height * 0.5) / height + this.noiseSpeed.y * this.dt; + const pix = this.getNoise(sampx, sampy, 0.0, this.dt, this.accSpeed, this.noiseFrequency, this.octaves); + out[h * width + w] = (pix + 1.0) * 0.5; + } + } + } +} diff --git a/cocos/particle/particle-culler.ts b/cocos/particle/particle-culler.ts index 2a692b33156..9fccdaa948a 100644 --- a/cocos/particle/particle-culler.ts +++ b/cocos/particle/particle-culler.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/restrict-plus-operands */ -/* eslint-disable max-len */ /* Copyright (c) 2020 Xiamen Yaji Software Co., Ltd. @@ -25,22 +23,17 @@ THE SOFTWARE. */ -import { EDITOR } from 'internal:constants'; import { IParticleModule, Particle, PARTICLE_MODULE_ORDER } from './particle'; import { Node } from '../core/scene-graph/node'; import { TransformBit } from '../core/scene-graph/node-enum'; import { RenderMode, Space } from './enum'; -import { Color, Mat4, Material, pseudoRandom, Quat, randomRangeInt, RenderingSubMesh, Vec3, Vec4 } from '../core'; +import { Mat4, pseudoRandom, Quat, randomRangeInt, Vec3, Vec4 } from '../core'; import { INT_MAX } from '../core/math/bits'; import { particleEmitZAxis } from './particle-general-function'; import { IParticleSystemRenderer } from './renderer/particle-system-renderer-base'; import { Mesh } from '../3d'; import { AABB } from '../core/geometry'; -import { scene } from '../core/renderer'; -import { BlendFactor } from '../core/gfx'; -import { Primitive } from '../primitive/primitive'; -import { Root } from '../core/root'; -import { legacyCC } from '../core/global-exports'; +import type { ParticleSystem } from './particle-system'; const _node_mat = new Mat4(); const _node_rol = new Quat(); @@ -57,7 +50,7 @@ const _anim_module = [ ]; export class ParticleCuller { - private _particleSystem: any; + private _particleSystem: ParticleSystem; private _processor: IParticleSystemRenderer; private _node: Node; private _particlesAll: Particle[]; @@ -96,7 +89,7 @@ export class ParticleCuller { this._updateBoundingNode(); } - public setBoundingBoxCenter (px, py, pz) { + public setBoundingBoxCenter (px: number, py: number, pz: number) { this.maxPos.x = px + this._nodeSize.x * 0.5; this.maxPos.y = py + this._nodeSize.y * 0.5; this.maxPos.z = pz + this._nodeSize.z * 0.5; @@ -264,13 +257,14 @@ export class ParticleCuller { } } + const worldMat = this._particleSystem.node.worldMatrix; for (let i = 0; i < this._particlesAll.length; ++i) { const p: Particle = this._particlesAll[i]; Vec3.multiply(size, _node_scale, p.size); Vec3.multiply(size, size, meshSize); position.set(p.position); if (this._particleSystem.simulationSpace !== Space.World) { - Vec3.transformMat4(position, position, this._particleSystem.node._mat); + Vec3.transformMat4(position, position, worldMat); } if (isInit && i === 0) { Vec3.subtract(this.minPos, position, size); diff --git a/cocos/particle/particle-system.ts b/cocos/particle/particle-system.ts index add9f1a3a09..b55e11fe255 100644 --- a/cocos/particle/particle-system.ts +++ b/cocos/particle/particle-system.ts @@ -24,8 +24,9 @@ */ // eslint-disable-next-line max-len -import { ccclass, help, executeInEditMode, executionOrder, menu, tooltip, displayOrder, type, range, displayName, formerlySerializedAs, override, radian, serializable, inspector, boolean, visible } from 'cc.decorator'; +import { ccclass, help, executeInEditMode, executionOrder, menu, tooltip, displayOrder, type, range, displayName, formerlySerializedAs, override, radian, serializable, visible } from 'cc.decorator'; import { EDITOR } from 'internal:constants'; +import { Renderer } from '../core/components/renderer'; import { ModelRenderer } from '../core/components/model-renderer'; import { Material } from '../core/assets/material'; import { Mat4, pseudoRandom, Quat, randomRangeInt, Vec2, Vec3 } from '../core/math'; @@ -53,7 +54,7 @@ import { TransformBit } from '../core/scene-graph/node-enum'; import { AABB, intersect } from '../core/geometry'; import { Camera } from '../core/renderer/scene'; import { ParticleCuller } from './particle-culler'; -import { Renderer } from '../core'; +import { NoiseModule } from './animator/noise-module'; const _world_mat = new Mat4(); const _world_rol = new Quat(); @@ -123,6 +124,7 @@ export class ParticleSystem extends ModelRenderer { @range([0, 1]) @displayOrder(10) @tooltip('i18n:particle_system.startSizeY') + @visible(function (this: ParticleSystem): boolean { return this.startSize3D; }) public startSizeY = new CurveRange(); /** @@ -133,6 +135,7 @@ export class ParticleSystem extends ModelRenderer { @range([0, 1]) @displayOrder(10) @tooltip('i18n:particle_system.startSizeZ') + @visible(function (this: ParticleSystem): boolean { return this.startSize3D; }) public startSizeZ = new CurveRange(); /** @@ -159,6 +162,7 @@ export class ParticleSystem extends ModelRenderer { @radian @displayOrder(12) @tooltip('i18n:particle_system.startRotationX') + @visible(function (this: ParticleSystem): boolean { return this.startRotation3D; }) public startRotationX = new CurveRange(); /** @@ -170,6 +174,7 @@ export class ParticleSystem extends ModelRenderer { @radian @displayOrder(12) @tooltip('i18n:particle_system.startRotationY') + @visible(function (this: ParticleSystem): boolean { return this.startRotation3D; }) public startRotationY = new CurveRange(); /** @@ -181,6 +186,7 @@ export class ParticleSystem extends ModelRenderer { @radian @displayOrder(12) @tooltip('i18n:particle_system.startRotationZ') + @visible(function (this: ParticleSystem): boolean { return this.startRotation3D; }) public startRotationZ = new CurveRange(); /** @@ -652,6 +658,27 @@ export class ParticleSystem extends ModelRenderer { this._textureAnimationModule = val; } + // noise module + @type(NoiseModule) + private _noiseModule: NoiseModule | null = null; + + @type(NoiseModule) + @displayOrder(24) + public get noiseModule () { + if (EDITOR) { + if (!this._noiseModule) { + this._noiseModule = new NoiseModule(); + this._noiseModule.bindTarget(this.processor); + } + } + return this._noiseModule; + } + + public set noiseModule (val) { + if (!val) return; + this._noiseModule = val; + } + // trail module @type(TrailModule) _trailModule: TrailModule | null = null; @@ -889,6 +916,14 @@ export class ParticleSystem extends ModelRenderer { this._isPaused = true; } + /** + * @zh 停止发射粒子。 + * @en Stop emitting particles. + */ + public stopEmitting () { + this._isEmitting = false; + } + /** * @en stop particle system * @zh 停止播放粒子。 @@ -903,6 +938,9 @@ export class ParticleSystem extends ModelRenderer { if (this._isPaused) { this._isPaused = false; } + if (this._isEmitting) { + this._isEmitting = false; + } this._time = 0.0; this._emitRateTimeCounter = 0.0; @@ -1282,13 +1320,14 @@ export class ParticleSystem extends ModelRenderer { // this._emitRateDistanceCounter = 0.0; if (!this.loop) { this._isEmitting = false; - return; } } + if (!this._isEmitting) return; + // emit by rateOverTime this._emitRateTimeCounter += this.rateOverTime.evaluate(this._time / this.duration, 1)! * dt; - if (this._emitRateTimeCounter > 1 && this._isEmitting) { + if (this._emitRateTimeCounter > 1) { const emitNum = Math.floor(this._emitRateTimeCounter); this._emitRateTimeCounter -= emitNum; this.emit(emitNum, dt); @@ -1300,7 +1339,7 @@ export class ParticleSystem extends ModelRenderer { Vec3.copy(this._oldWPos, this._curWPos); this._emitRateDistanceCounter += distance * this.rateOverDistance.evaluate(this._time / this.duration, 1)!; - if (this._emitRateDistanceCounter > 1 && this._isEmitting) { + if (this._emitRateDistanceCounter > 1) { const emitNum = Math.floor(this._emitRateDistanceCounter); this._emitRateDistanceCounter -= emitNum; this.emit(emitNum, dt); @@ -1400,4 +1439,12 @@ export class ParticleSystem extends ModelRenderer { // eslint-disable-next-line @typescript-eslint/no-unsafe-return return this.dataCulling ? props.filter((p) => !PARTICLE_MODULE_PROPERTY.includes(p) || (this[p] && this[p].enable)) : props; } + + public getNoisePreview (width: number, height: number): number[] { + const out: number[] = []; + if (this.processor) { + this.processor.getNoisePreview(out, width, height); + } + return out; + } } diff --git a/cocos/particle/particle.ts b/cocos/particle/particle.ts index 99988652a99..a7e2e9c09a7 100644 --- a/cocos/particle/particle.ts +++ b/cocos/particle/particle.ts @@ -110,6 +110,7 @@ export const PARTICLE_MODULE_NAME = { SIZE: 'sizeModule', VELOCITY: 'velocityModule', TEXTURE: 'textureModule', + NOISE: 'noiseModule', }; export const PARTICLE_MODULE_ORDER = [ @@ -120,6 +121,7 @@ export const PARTICLE_MODULE_ORDER = [ 'limitModule', 'rotationModule', 'textureModule', + 'noiseModule', ]; export const PARTICLE_MODULE_PROPERTY = [ @@ -131,6 +133,7 @@ export const PARTICLE_MODULE_PROPERTY = [ '_limitVelocityOvertimeModule', '_rotationOvertimeModule', '_textureAnimationModule', + '_noiseModule', '_trailModule', ]; diff --git a/cocos/particle/renderer/particle-system-renderer-base.ts b/cocos/particle/renderer/particle-system-renderer-base.ts index baf058844f8..5ec699941d6 100644 --- a/cocos/particle/renderer/particle-system-renderer-base.ts +++ b/cocos/particle/renderer/particle-system-renderer-base.ts @@ -62,6 +62,7 @@ export interface IParticleSystemRenderer { beforeRender (): void; setUseInstance (value: boolean): void; getUseInstance (): boolean; + getNoisePreview (out: number[], width: number, height: number): void; } export abstract class ParticleSystemRendererBase implements IParticleSystemRenderer { @@ -168,4 +169,5 @@ export abstract class ParticleSystemRendererBase implements IParticleSystemRende public abstract enableModule (name: string, val: boolean, pm: IParticleModule): void; public abstract beforeRender (): void; public abstract setUseInstance (value: boolean): void; + public abstract getNoisePreview (out: number[], width: number, height: number): void; } diff --git a/cocos/particle/renderer/particle-system-renderer-cpu.ts b/cocos/particle/renderer/particle-system-renderer-cpu.ts index 3deab7d4731..34600a58bc4 100644 --- a/cocos/particle/renderer/particle-system-renderer-cpu.ts +++ b/cocos/particle/renderer/particle-system-renderer-cpu.ts @@ -27,16 +27,18 @@ import { EDITOR } from 'internal:constants'; import { builtinResMgr } from '../../core/builtin'; import { Material } from '../../core/assets'; import { AttributeName, Format, Attribute } from '../../core/gfx'; -import { Mat4, Vec2, Vec3, Vec4, pseudoRandom, Quat } from '../../core/math'; +import { Mat4, Vec2, Vec3, Vec4, pseudoRandom, Quat, random } from '../../core/math'; import { RecyclePool } from '../../core/memop'; import { MaterialInstance, IMaterialInstanceInfo } from '../../core/renderer/core/material-instance'; import { MacroRecord } from '../../core/renderer/core/pass-utils'; import { AlignmentSpace, RenderMode, Space } from '../enum'; -import { Particle, IParticleModule, PARTICLE_MODULE_ORDER } from '../particle'; +import { Particle, IParticleModule, PARTICLE_MODULE_ORDER, PARTICLE_MODULE_NAME } from '../particle'; import { ParticleSystemRendererBase } from './particle-system-renderer-base'; import { Component } from '../../core'; import { Camera } from '../../core/renderer/scene/camera'; import { Pass } from '../../core/renderer'; +import { ParticleNoise } from '../noise'; +import { NoiseModule } from '../animator/noise-module'; import { legacyCC } from '../../core/global-exports'; const _tempAttribUV = new Vec3(); @@ -52,6 +54,7 @@ const _anim_module = [ '_limitVelocityOvertimeModule', '_rotationOvertimeModule', '_textureAnimationModule', + '_noiseModule', ]; const _uvs = [ @@ -342,6 +345,8 @@ export default class ParticleSystemRendererCPU extends ParticleSystemRendererBas pass.setUniform(this._uScaleHandle, this._node_scale); } + private noise: ParticleNoise = new ParticleNoise(); + public updateParticles (dt: number) { const ps = this._particleSystem; if (!ps) { @@ -415,6 +420,15 @@ export default class ParticleSystemRendererCPU extends ParticleSystemRendererBas return this._particles!.length; } + public getNoisePreview (out: number[], width: number, height: number) { + this._runAnimateList.forEach((value) => { + if (value.name === PARTICLE_MODULE_NAME.NOISE) { + const m = value as NoiseModule; + m.getNoisePreview(out, this._particleSystem, width, height); + } + }); + } + // internal function public updateRenderData () { // update vertex buffer diff --git a/cocos/particle/renderer/particle-system-renderer-gpu.ts b/cocos/particle/renderer/particle-system-renderer-gpu.ts index 446f6c6a529..5262ef36954 100644 --- a/cocos/particle/renderer/particle-system-renderer-gpu.ts +++ b/cocos/particle/renderer/particle-system-renderer-gpu.ts @@ -603,4 +603,8 @@ export default class ParticleSystemRendererGPU extends ParticleSystemRendererBas } this.updateRenderMode(); } + + public getNoisePreview (out: number[], width: number, height: number) { + + } } diff --git a/editor/assets/chunks/builtin/functionalities/skinning-animation-dqs.chunk b/editor/assets/chunks/builtin/functionalities/skinning-animation-dqs.chunk index 5ac58535a01..699ac3681b0 100644 --- a/editor/assets/chunks/builtin/functionalities/skinning-animation-dqs.chunk +++ b/editor/assets/chunks/builtin/functionalities/skinning-animation-dqs.chunk @@ -35,12 +35,48 @@ } #endif #else - void getJointDQ (float i, out vec4 Qr, out vec4 Qt, out vec3 S) { - int idx = int(i); - Qr = cc_joints[idx * 3]; - Qt = cc_joints[idx * 3 + 1]; - S = cc_joints[idx * 3 + 2].xyz; - } + #if CC_USE_REAL_TIME_JOINT_TEXTURE + #if CC_DEVICE_SUPPORT_FLOAT_TEXTURE + void getJointDQ (float i, out vec4 Qr, out vec4 Qt, out vec3 S) { + float x = i; + Qr = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0)); + Qt = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0)); + S = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0)).xyz; + } + #else + void getJointDQ (float i, out vec4 Qr, out vec4 Qt, out vec3 S) { + float x = 4.0 * i; + vec4 v1 = vec4( + decode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0))) + ); + vec4 v2 = vec4( + decode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0))) + ); + vec4 v3 = vec4( + decode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0))) + ); + Qr = v1; + Qt = v2; + S = v3.xyz; + } + #endif + #else + void getJointDQ (float i, out vec4 Qr, out vec4 Qt, out vec3 S) { + int idx = int(i); + Qr = cc_joints[idx * 3]; + Qt = cc_joints[idx * 3 + 1]; + S = cc_joints[idx * 3 + 2].xyz; + } + #endif #endif // [Kavan07] Skinning with Dual Quaternions diff --git a/editor/assets/chunks/builtin/functionalities/skinning-animation-lbs.chunk b/editor/assets/chunks/builtin/functionalities/skinning-animation-lbs.chunk index a9f1385c6ea..91799f39e02 100644 --- a/editor/assets/chunks/builtin/functionalities/skinning-animation-lbs.chunk +++ b/editor/assets/chunks/builtin/functionalities/skinning-animation-lbs.chunk @@ -38,13 +38,48 @@ } #endif #else - mat4 getJointMatrix (float i) { - int idx = int(i); - vec4 v1 = cc_joints[idx * 3]; - vec4 v2 = cc_joints[idx * 3 + 1]; - vec4 v3 = cc_joints[idx * 3 + 2]; - return mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0)); - } + #if CC_USE_REAL_TIME_JOINT_TEXTURE + #if CC_DEVICE_SUPPORT_FLOAT_TEXTURE + mat4 getJointMatrix (float i) { + float x = i; + vec4 v1 = texture(cc_realtimeJoint, vec2( x / 256.0, 0.5 / 3.0)); + vec4 v2 = texture(cc_realtimeJoint, vec2( x / 256.0, 1.5 / 3.0)); + vec4 v3 = texture(cc_realtimeJoint, vec2( x / 256.0, 2.5 / 3.0)); + return mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0)); + } + #else + mat4 getJointMatrix (float i) { + float x = 4.0 * i; + vec4 v1 = vec4( + decode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 0.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 0.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 0.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 0.5 / 3.0))) + ); + vec4 v2 = vec4( + decode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 1.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 1.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 1.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 1.5 / 3.0))) + ); + vec4 v3 = vec4( + decode32(texture(cc_realtimeJoint, vec2((x + 0.5)/ 1024.0, 2.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 1.5)/ 1024.0, 2.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 2.5)/ 1024.0, 2.5 / 3.0))), + decode32(texture(cc_realtimeJoint, vec2((x + 3.5)/ 1024.0, 2.5 / 3.0))) + ); + return mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0)); + } + #endif + #else + mat4 getJointMatrix (float i) { + int idx = int(i); + vec4 v1 = cc_joints[idx * 3]; + vec4 v2 = cc_joints[idx * 3 + 1]; + vec4 v3 = cc_joints[idx * 3 + 2]; + return mat4(vec4(v1.xyz, 0.0), vec4(v2.xyz, 0.0), vec4(v3.xyz, 0.0), vec4(v1.w, v2.w, v3.w, 1.0)); + } + #endif #endif mat4 skinMatrix () { diff --git a/editor/assets/chunks/builtin/uniforms/cc-skinning.chunk b/editor/assets/chunks/builtin/uniforms/cc-skinning.chunk index 1849e1ca6b0..5a4d4806eeb 100644 --- a/editor/assets/chunks/builtin/uniforms/cc-skinning.chunk +++ b/editor/assets/chunks/builtin/uniforms/cc-skinning.chunk @@ -31,9 +31,13 @@ y = (tempY + 0.5) * invSize; } #else - #pragma define JOINT_UNIFORM_CAPACITY 30 - #pragma builtin(local) - layout(set = 2, binding = 3) uniform CCSkinning { - highp vec4 cc_joints[JOINT_UNIFORM_CAPACITY * 3]; - }; + #if CC_USE_REAL_TIME_JOINT_TEXTURE + #pragma builtin(local) + layout(set = 2, binding = 6) uniform highp sampler2D cc_realtimeJoint; + #else + #pragma builtin(local) + layout(set = 2, binding = 3) uniform CCSkinning { + highp vec4 cc_joints[CC_JOINT_UNIFORM_CAPACITY * 3]; + }; + #endif #endif diff --git a/editor/assets/effects/surfaces/standard.effect b/editor/assets/effects/surfaces/standard.effect index 8da9b495a91..54a73ad84b3 100644 --- a/editor/assets/effects/surfaces/standard.effect +++ b/editor/assets/effects/surfaces/standard.effect @@ -208,7 +208,6 @@ CCProgram surface-fragment %{ return baseColor; } - #define CC_SURFACES_FRAGMENT_MODIFY_WORLD_NORMAL vec3 SurfacesFragmentModifyWorldNormal() { @@ -226,9 +225,9 @@ CCProgram surface-fragment %{ { float anisotropyRotation = anisotropyParam.y; float anisotropyShape = anisotropyParam.x; -#if IS_ANISOTROPY && USE_ANISOTROPY_ROTATION_MAP + #if IS_ANISOTROPY && USE_ANISOTROPY_ROTATION_MAP anisotropyRotation = fract(anisotropyRotation + texture(anisotropyRotationMap, DEFAULT_UV).x); -#endif + #endif return vec4(anisotropyRotation, anisotropyShape, 0.0, 0.0); } diff --git a/editor/exports/embedded-player.ts b/editor/exports/embedded-player.ts new file mode 100644 index 00000000000..43a809e5098 --- /dev/null +++ b/editor/exports/embedded-player.ts @@ -0,0 +1,15 @@ +export { + embeddedPlayerCountTag, + getEmbeddedPlayersTag, + addEmbeddedPlayerTag, + removeEmbeddedPlayerTag, + clearEmbeddedPlayersTag, +} from '../../cocos/core/animation/animation-clip'; + +export { EmbeddedPlayer } from '../../cocos/core/animation/embedded-player/embedded-player'; + +export type { EmbeddedPlayable } from '../../cocos/core/animation/embedded-player/embedded-player'; + +export { EmbeddedParticleSystemPlayable } from '../../cocos/core/animation/embedded-player/embedded-particle-system-player'; + +export { EmbeddedAnimationClipPlayable } from '../../cocos/core/animation/embedded-player/embedded-animation-clip-player'; diff --git a/editor/inspector/assets/animation-mask.js b/editor/inspector/assets/animation-mask.js index 319e0b542e4..1aa3987e31b 100644 --- a/editor/inspector/assets/animation-mask.js +++ b/editor/inspector/assets/animation-mask.js @@ -17,43 +17,52 @@ exports.template = ` `; exports.methods = { - updateReadonly(element) { - if (this.asset.readonly) { - element.setAttribute('disabled', true); - } else { - element.removeAttribute('disabled'); + record() { + return JSON.stringify(this.queryData); + }, + + async restore(record) { + record = JSON.parse(record); + if (!record || typeof record !== 'object') { + return false; } + + this.queryData = await Editor.Message.request('scene', 'change-animation-mask', { + method: 'change-dump', + dump: record, + }); + await this.changed({ snapshot: false }); + return true; }, + async query(uuid) { - this.queryData = await Editor.Message.request('scene', 'query-animation-mask', uuid); - this.updateTree(); + return await Editor.Message.request('scene', 'query-animation-mask', uuid); }, async apply() { this.reset(); await Editor.Message.request('scene', 'apply-animation-mask', this.asset.uuid); }, reset() { - this.dirtyData.origin = this.dirtyData.realtime; this.dirtyData.uuid = ''; }, - async dataChange() { - await Editor.Message.request('scene', 'change-animation-mask', { - method: 'change-dump', - dump: this.queryData, - }); - + async changed(state) { + this.updateInterface(); this.setDirtyData(); - this.dispatch('change'); + + this.dispatch('change', state); }, - jointEnableChange(key, checked, loop) { - const { children, origin } = this.flatData[key]; - origin.value.enabled.value = checked; + updateInterface() { + const convertData = this.convertData(this.queryData.joints.value); + this.flatData = convertData.flatData; + this.$.tree.tree = convertData.treeData; + }, - if (loop) { - children.forEach((childKey) => { - this.jointEnableChange(childKey, checked, loop); - }); + updateReadonly(element) { + if (this.asset.readonly) { + element.setAttribute('disabled', true); + } else { + element.removeAttribute('disabled'); } }, @@ -65,6 +74,8 @@ exports.methods = { if (!this.dirtyData.origin) { this.dirtyData.origin = this.dirtyData.realtime; + + this.dispatch('snapshot'); } }, @@ -159,10 +170,15 @@ exports.methods = { return { flatData, treeData }; }, - updateTree() { - const convertData = this.convertData(this.queryData.joints.value); - this.flatData = convertData.flatData; - this.$.tree.tree = convertData.treeData; + jointEnableChange(key, checked, loop) { + const { children, origin } = this.flatData[key]; + origin.value.enabled.value = checked; + + if (loop) { + children.forEach((childKey) => { + this.jointEnableChange(childKey, checked, loop); + }); + } }, }; @@ -229,9 +245,7 @@ exports.ready = function() { uuid: info.redirect.uuid, }); - panel.updateTree(); - panel.setDirtyData(); - panel.dispatch('change'); + panel.changed(); }, }, }); @@ -251,9 +265,7 @@ exports.ready = function() { uuid: this.asset.uuid, }); - panel.updateTree(); - panel.setDirtyData(); - panel.dispatch('change'); + this.changed(); } }); @@ -267,12 +279,17 @@ exports.ready = function() { panel.$.tree.setTemplate('left', ''); panel.$.tree.setTemplateInit('left', ($left) => { $left.$checkbox = $left.querySelector('ui-checkbox'); - $left.$checkbox.addEventListener('click', (event) => { + $left.$checkbox.addEventListener('click', async (event) => { const key = $left.data.detail.key; const origin = panel.flatData[key].origin; panel.jointEnableChange(key, !origin.value.enabled.value, !event.altKey); - panel.dataChange(); - panel.$.tree.render(); + + panel.queryData = await Editor.Message.request('scene', 'change-animation-mask', { + method: 'change-dump', + dump: panel.queryData, + }); + + panel.changed(); }); }); panel.$.tree.setRender('left', ($left) => { @@ -307,7 +324,7 @@ exports.update = async function(assetList, metaList) { this.meta = metaList[0]; if (assetList.length !== 1) { - this.$.container.innerText = ''; + this.$.container.innerText = Editor.I18n.t('ENGINE.assets.multipleWarning'); return; } @@ -316,8 +333,9 @@ exports.update = async function(assetList, metaList) { this.dirtyData.origin = ''; } - await this.query(this.asset.uuid); + this.queryData = await this.query(this.asset.uuid); + this.updateInterface(); this.setDirtyData(); }; diff --git a/editor/inspector/assets/material.js b/editor/inspector/assets/material.js index c84a8b1e99a..30d6f0831d7 100644 --- a/editor/inspector/assets/material.js +++ b/editor/inspector/assets/material.js @@ -5,10 +5,19 @@ const { setDisabled, setReadonly, setHidden, loopSetAssetDumpDataReadonly } = re const { join, sep, normalize } = require('path'); exports.style = ` +.invalid { display: none; } +.invalid[active] { display: block; } +.invalid[active] ~ * { display: none; } + +.custom[src] + .default { display: none; } + ui-button.location { flex: none; margin-left: 4px; } `; exports.template = /* html */ ` +
+ +
Effect @@ -22,28 +31,28 @@ exports.template = /* html */ `
-
- -
-
- - -
-
+ +
+
+ + +
+
+
`; exports.$ = { - pass: '.pass', + invalid: '.invalid', + header: '.header', - section: '.section', effect: '.effect', location: '.location', technique: '.technique', - materialDump: '.material-dump', useInstancing: '.useInstancing', useBatching: '.useBatching', - customSection: '.customSection', - customPanel: '.customPanel', + materialDump: '.material-dump', + + custom: '.custom', }; exports.methods = { @@ -62,132 +71,114 @@ exports.methods = { this.material = record.material; this.cacheData = record.cacheData; - await this.updateInterface({ snapshot: false }); + await this.updateEffect(); + + await this.updateInterface(); + + await this.change({ snapshot: false }); return true; }, - async getCustomInspector() { - const currentEffectInfo = this._effects.find((effect) => { - return effect.name === this.material.effect; - }); - if (currentEffectInfo && currentEffectInfo.uuid) { - const meta = await Editor.Message.request('asset-db', 'query-asset-meta', currentEffectInfo.uuid); - return meta && meta.userData && meta.userData.editor && meta.userData.editor.inspector; - } - return ''; - }, - /** - * Custom Save - */ async apply() { this.reset(); await Editor.Message.request('scene', 'apply-material', this.asset.uuid, this.material); }, reset() { - this.dirtyData.origin = this.dirtyData.realtime; this.dirtyData.uuid = ''; this.cacheData = {}; }, - /** - * - * @param {string} inspector - */ - async updateCustomInspector(inspector) { - this.$.customPanel.hidden = false; - this.$.section.hidden = true; - this.$.materialDump.hidden = true; - try { - if (inspector.startsWith('packages://')) { - const relatePath = normalize(inspector.replace('packages://', '')); - const name = relatePath.split(sep)[0]; - const packagePath = Editor.Package.getPackages({ name, enable: true })[0].path; - const path = join(packagePath, relatePath.split(name)[1]); - if (this.$.customPanel.getAttribute('src') !== path) { - this.$.customPanel.setAttribute('src', path); - } - this.$.customPanel.update(this.material, this.assetList, this.metaList); - } else { - throw Editor.I18n.t('ENGINE.assets.material.illegal-inspector-url'); - } - } catch (error) { - console.error(error); - console.error(Editor.I18n.t('ENGINE.assets.material.fail-to-load-custom-inspector', { effect: this.material.effect })); - this.updatePasses(); - } - }, - /** - * Detection of data changes only determines the currently selected technique - */ - setDirtyData(state) { - this.dirtyData.realtime = JSON.stringify({ - effect: this.material.effect, - technique: this.material.technique, - techniqueData: this.material.data[this.material.technique], - }); - if (!this.dirtyData.origin) { - this.dirtyData.origin = this.dirtyData.realtime; + async change(state) { + this.canUpdatePreview = true; + this.setDirtyData(); - this.dispatch('snapshot'); - } else { - this.dispatch('change', state); + if (this.canUpdatePreview) { + this.updatePreview(); } - this.canUpdatePreview = true; + this.dispatch('change', state); }, - isDirty() { - const isDirty = this.dirtyData.origin !== this.dirtyData.realtime; - return isDirty; - }, + async updateEffect() { + const effectMap = await Editor.Message.request('scene', 'query-all-effects'); + this.effects = Object.keys(effectMap).sort().filter((name) => { + const effect = effectMap[name]; + return !effect.hideInEditor; + }).map((name) => { + const effect = effectMap[name]; + return { + name, + uuid: effect.uuid, + }; + }); - async updateInterface(state) { - if (this.canUpdatePreview) { - await this.updatePreview(); + let effectOption = ''; + for (let effect of this.effects) { + effectOption += ``; } + this.$.effect.innerHTML = effectOption; - // effect tag - this.$.technique.value = this.material.technique; - setDisabled(this.asset.readonly, this.$.technique); + }, + + async updateInterface() { + this.updateTechnique(); + + const currentEffectInfo = this.effects.find((effect) => { + return effect.name === this.material.effect; + }); - this.updateTechniqueOptions(); + this.customInterface = ''; + if (currentEffectInfo && currentEffectInfo.uuid) { + const meta = await Editor.Message.request('asset-db', 'query-asset-meta', currentEffectInfo.uuid); + if (meta && meta.userData && meta.userData.editor) { + this.customInterface = meta.userData.editor.inspector; + } + } - const inspector = await this.getCustomInspector(); - if (inspector) { - this.updateCustomInspector(inspector); - this.setDirtyData(state); + if (this.customInterface && this.customInterface.startsWith('packages://')) { + try { + const relatePath = normalize(this.customInterface.replace('packages://', '')); + const name = relatePath.split(sep)[0]; + + const packagePath = Editor.Package.getPackages({ name, enable: true })[0].path; + + const filePath = join(packagePath, relatePath.split(name)[1]); + if (this.$.custom.getAttribute('src') !== filePath) { + this.$.custom.setAttribute('src', filePath); + } + + this.$.custom.update(this.material, this.assetList, this.metaList); + + } catch (err) { + console.error(err); + console.error(Editor.I18n.t('ENGINE.assets.material.illegal-inspector-url')); + } } else { - // optimize calculate speed when edit multiple materials in node mode - requestIdleCallback(() => { - this.updatePasses(); - this.setDirtyData(state); - }); + this.$.custom.removeAttribute('src'); + this.updatePasses(); } }, - /** - * Update the pass data that is finally displayed in the panel - */ - updatePasses() { - if (this.$.customPanel.hasAttribute('src')) { - this.$.customPanel.removeAttribute('src'); - } - this.$.customPanel.hidden = true; - this.$.section.hidden = false; - this.$.materialDump.hidden = false; - // Automatic rendering of content - // The data in passes is not all the values that need to be rendered - // So it's sorted here, but that doesn't make sense - // The logical way to do it would be to return a normal dump when querying for material + updateTechnique() { + let techniqueOption = ''; + this.material.data.forEach((technique, index) => { + const name = technique.name ? `${index} - ${technique.name}` : index; + techniqueOption += ``; + }); + this.$.technique.innerHTML = techniqueOption; + this.$.technique.value = this.material.technique; + setDisabled(this.asset.readonly, this.$.technique); + }, + + updatePasses() { const technique = materialTechniquePolyfill(this.material.data[this.material.technique]); - this.technique = technique; + this.technique = technique; if (!technique || !technique.passes) { return; } @@ -219,7 +210,6 @@ exports.methods = { $container.$children[i] = document.createElement('ui-prop'); $container.$children[i].setAttribute('type', 'dump'); - $container.$children[i].setAttribute('fold', 'false'); $container.appendChild($container.$children[i]); $container.$children[i].render(pass); @@ -269,6 +259,14 @@ exports.methods = { if (Array.from($prop.$children.children).length) { $prop.after($prop.$children); } + + $prop.addEventListener('change-dump', (e) => { + if (e.target.dump.value) { + $prop.$children.removeAttribute('hidden'); + } else { + $prop.$children.setAttribute('hidden', ''); + } + }); } if (dump.value) { @@ -280,6 +278,10 @@ exports.methods = { }); } } + + this.updateInstancing(); + + this.updatePreview(); }, updateInstancing() { @@ -310,6 +312,11 @@ exports.methods = { } }, + async updatePreview() { + await Editor.Message.request('scene', 'preview-material', this.asset.uuid, this.material); + Editor.Message.broadcast('material-inspector:change-dump'); + }, + changeInstancing(checked) { this.technique.passes.forEach((pass) => { if (pass.childMap.USE_INSTANCING) { @@ -324,6 +331,7 @@ exports.methods = { this.$.useBatching.render(this.technique.useBatching); } }, + changeBatching(checked) { this.technique.passes.forEach((pass) => { if (pass.childMap.USE_BATCHING) { @@ -331,27 +339,6 @@ exports.methods = { } }); }, - /** - * Update the options data in technique - */ - updateTechniqueOptions() { - let techniqueOption = ''; - this.material.data.forEach((technique, index) => { - const name = technique.name ? `${index} - ${technique.name}` : index; - techniqueOption += ``; - }); - this.$.technique.innerHTML = techniqueOption; - }, - hideAllContent(hide) { - this.$.header.style = hide ? 'display:none' : ''; - this.$.section.style = hide ? 'display:none' : ''; - this.$.materialDump.style = hide ? 'display:none' : ''; - }, - - async updatePreview() { - await Editor.Message.request('scene', 'preview-material', this.asset.uuid, this.material); - Editor.Message.broadcast('material-inspector:change-dump'); - }, initCache() { const excludeNames = [ @@ -444,10 +431,25 @@ exports.methods = { } } } + }, - // Update the extracted useInstancing and useBatching - this.updateInstancing(); - this.updatePreview(); + setDirtyData() { + this.dirtyData.realtime = JSON.stringify({ + effect: this.material.effect, + technique: this.material.technique, + techniqueData: this.material.data[this.material.technique], + }); + + if (!this.dirtyData.origin) { + this.dirtyData.origin = this.dirtyData.realtime; + + this.dispatch('snapshot'); + } + }, + + isDirty() { + const isDirty = this.dirtyData.origin !== this.dirtyData.realtime; + return isDirty; }, }; @@ -461,14 +463,14 @@ exports.update = async function(assetList, metaList) { this.metaList = metaList; this.asset = assetList[0]; this.meta = metaList[0]; - const notOnlyOne = assetList.length !== 1; - this.hideAllContent(notOnlyOne); - if (notOnlyOne) { - return; - } - if (!this.dirtyData) { + + if (assetList.length !== 1) { + this.$.invalid.setAttribute('active', ''); return; + } else { + this.$.invalid.removeAttribute('active'); } + if (this.dirtyData.uuid !== this.asset.uuid) { this.dirtyData.uuid = this.asset.uuid; this.dirtyData.origin = ''; @@ -476,10 +478,13 @@ exports.update = async function(assetList, metaList) { this.cacheData = {}; this.requestInitCache = true; } - // set this.material.technique + this.material = await Editor.Message.request('scene', 'query-material', this.asset.uuid); + await this.updateEffect(); + await this.updateInterface(); + this.setDirtyData(); }; /** @@ -497,47 +502,20 @@ exports.ready = async function() { // Retain the previously modified data when switching pass this.cacheData = {}; - // The event triggered when the content of material is modified - this.$.materialDump.addEventListener('change-dump', async (event) => { - const dump = event.target.dump; - - // show its children - if (dump && dump.childMap && dump.children.length && event.target.$children) { - if (dump.value) { - event.target.$children.removeAttribute('hidden'); - } else { - event.target.$children.setAttribute('hidden', ''); - } - } - - this.setDirtyData(); - this.storeCache(dump); - - await this.updatePreview(); - }); - // The event that is triggered when the effect used is modified this.$.effect.addEventListener('change', async (event) => { this.material.effect = event.target.value; this.material.data = await Editor.Message.request('scene', 'query-effect', this.material.effect); - this.updateTechniqueOptions(); - if (!this.material.data[this.material.technique]) { - this.$.technique.value = this.material.technique = 0; - } else { - this.$.technique.value = this.material.technique; - } - const inspector = await this.getCustomInspector(); - if (inspector) { - this.updateCustomInspector(inspector); - } else { - this.updatePasses(); - } - this.setDirtyData(); + this.$.technique.value = this.material.technique = 0; + + await this.updateInterface(); + + this.change(); }); this.$.location.addEventListener('change', () => { - const effect = this._effects.find((_effect) => _effect.name === this.material.effect); + const effect = this.effects.find((_effect) => _effect.name === this.material.effect); if (effect) { Editor.Message.send('assets', 'twinkle', effect.uuid); } @@ -546,56 +524,43 @@ exports.ready = async function() { // Event triggered when the technique being used is changed this.$.technique.addEventListener('change', async (event) => { this.material.technique = event.target.value; - - const inspector = await this.getCustomInspector(); - if (inspector) { - this.updateCustomInspector(inspector); - } else { - this.updatePasses(); - } - this.setDirtyData(); - this.updatePreview(); + await this.updateInterface(); + this.change(); }); // The event is triggered when the useInstancing is modified this.$.useInstancing.addEventListener('change-dump', (event) => { this.changeInstancing(event.target.dump.value); this.storeCache(event.target.dump); - this.setDirtyData(); - this.updatePreview(); + this.change(); }); // The event is triggered when the useBatching is modified this.$.useBatching.addEventListener('change-dump', (event) => { this.changeBatching(event.target.dump.value); this.storeCache(event.target.dump); - this.setDirtyData(); - this.updatePreview(); + this.change(); }); - // When the page is initialized, all effect lists are queried and then not updated again - const effectMap = await Editor.Message.request('scene', 'query-all-effects'); - this._effects = Object.keys(effectMap) - .sort() - .filter((name) => { - const effect = effectMap[name]; - return !effect.hideInEditor; - }) - .map((name) => { - const effect = effectMap[name]; - return { - name, - uuid: effect.uuid, - }; - }); - let effectOption = ''; - for (let effect of this._effects) { - effectOption += ``; - } - this.$.effect.innerHTML = effectOption; - this.$.customPanel.addEventListener('change', () => { - this.setDirtyData(); - this.updatePreview(); + // The event triggered when the content of material is modified + this.$.materialDump.addEventListener('change-dump', async (event) => { + const dump = event.target.dump; + + // // show its children + // if (dump && dump.childMap && dump.children.length && event.target.$children) { + // if (dump.value) { + // event.target.$children.removeAttribute('hidden'); + // } else { + // event.target.$children.setAttribute('hidden', ''); + // } + // } + + this.storeCache(dump); + this.change(); + }); + + this.$.custom.addEventListener('change', () => { + this.change(); }); }; diff --git a/editor/inspector/assets/physics-material.js b/editor/inspector/assets/physics-material.js index 5bdf31d747e..e01314668b6 100644 --- a/editor/inspector/assets/physics-material.js +++ b/editor/inspector/assets/physics-material.js @@ -7,6 +7,7 @@ exports.methods = { record() { return JSON.stringify(this.physicsMaterial); }, + async restore(record) { record = JSON.parse(record); if (!record || typeof record !== 'object') { diff --git a/editor/inspector/assets/render-pipeline.js b/editor/inspector/assets/render-pipeline.js index 7b709847387..c7e5605c8ee 100644 --- a/editor/inspector/assets/render-pipeline.js +++ b/editor/inspector/assets/render-pipeline.js @@ -1,203 +1,23 @@ -const { setDisabled, loopSetAssetDumpDataReadonly } = require('../utils/prop'); - exports.template = ` -
-
- - Pipelines - - -
-
-
-
-`; - -exports.$ = { - container: '.asset-render-pipeline', - header: '.header', - content: '.content', - pipelinesSelect: '.pipelines-select', -}; - -exports.style = ` - .asset-render-pipeline > .header { - padding-bottom: 8px; - margin-bottom: 4px; - border-bottom: 1px var(--color-normal-border) dashed; - } + + `; -const Elements = { - pipelines: { - ready() { - const panel = this; - - panel.$.pipelinesSelect.addEventListener('change', async (event) => { - panel.$.content.removeAttribute('hidden'); - - panel.pipelineIndex = event.target.value; - - panel.pipeline = await Editor.Message.request('scene', 'select-render-pipeline', panel.pipelines[panel.pipelineIndex].name); - Elements.pipeline.update.call(panel); - - panel.setDirtyData(); - panel.dispatch('change'); - }); - }, - async update() { - const panel = this; - - let optionsHtml = ''; - panel.pipelines.forEach((pipeline, index) => { - optionsHtml += ``; - }); - panel.$.pipelinesSelect.innerHTML = optionsHtml; - - panel.$.pipelinesSelect.value = panel.pipelines.findIndex((one) => one.name === panel.pipeline.name); - - setDisabled(panel.asset.readonly, panel.$.pipelinesSelect); - }, - }, - pipeline: { - async update() { - const panel = this; - - const $content = panel.$.content; - const oldPropList = Object.keys(panel.$propList); - const newPropList = []; - - if (panel.$.pipelinesSelect.value === '-1') { - $content.setAttribute('hidden', ''); - return; - } else { - $content.removeAttribute('hidden'); - } - - for (const key in panel.pipeline.value) { - const dump = panel.pipeline.value[key]; - if (panel.asset.readonly) { - loopSetAssetDumpDataReadonly(dump); - } - - if (!dump.visible) { - continue; - } - - const id = `${dump.type}:${dump.name}`; - newPropList.push(id); - - let $prop = this.$propList[id]; - if (!$prop) { - $prop = document.createElement('ui-prop'); - $prop.setAttribute('type', 'dump'); - $prop.addEventListener('change-dump', this.change.bind(this)); - - $content.appendChild($prop); - panel.$propList[id] = $prop; - } - - $prop.render(dump); - } - - for (const id of oldPropList) { - if (!newPropList.includes(id)) { - const $prop = panel.$propList[id]; - if ($prop && $prop.parentElement) { - $prop.parentElement.removeChild($prop); - } - } - } - }, - }, -}; - -exports.update = async function(assetList, metaList) { - this.assetList = assetList; - this.metaList = metaList; - this.meta = this.metaList[0]; - this.asset = this.assetList[0]; - - if (assetList.length !== 1) { - this.$.container.setAttribute('hidden', ''); - return; - } else { - this.$.container.removeAttribute('hidden'); - } - - if (this.dirtyData.uuid !== this.asset.uuid) { - this.dirtyData.uuid = this.asset.uuid; - this.dirtyData.origin = ''; - } - - this.pipeline = await this.query(this.asset.uuid); - this.pipelines = await Editor.Message.request('scene', 'query-all-render-pipelines'); - - for (const prop in Elements) { - const element = Elements[prop]; - if (element.update) { - await element.update.call(this); - } - } - - this.setDirtyData(); - await this.preview(); -}; - -exports.ready = function() { - // Used to determine whether the material has been modified in isDirty() - this.dirtyData = { - uuid: '', - origin: '', - realtime: '', - }; - - this.$propList = {}; - - for (const prop in Elements) { - const element = Elements[prop]; - if (element.ready) { - element.ready.call(this); - } - } -}; - -exports.close = function() { - // Used to determine whether the material has been modified in isDirty() - this.dirtyData = { - uuid: '', - origin: '', - realtime: '', - }; - - this.$propList = {}; -}; - exports.methods = { record() { return JSON.stringify(this.pipeline); }, - async restore(record) { - // TODO: renderPipeline 编辑机制需要重新优化,目前有点乱, undo 后的数据无法正确还原 - // record = JSON.parse(record); - // if (!record || typeof record !== 'object') { - // return; - // } - - // this.pipeline = await Editor.Message.request('scene', 'change-render-pipeline', record); - // Elements.pipeline.update.call(this); + async restore(record) { + record = JSON.parse(record); + if (!record || typeof record !== 'object') { + return false; + } - // this.setDirtyData(); - // this.dispatch('change'); - // await this.preview(); - }, + this.pipeline = record; + await this.change({ snapshot: false }); - async preview() { - if (!this.pipeline) { - return; - } - await Editor.Message.request('scene', 'preview-render-pipeline', this.asset.uuid, this.pipeline); + return true; }, async query(uuid) { @@ -207,21 +27,35 @@ exports.methods = { async apply() { this.reset(); await Editor.Message.request('scene', 'apply-render-pipeline', this.asset.uuid, this.pipeline); - await this.preview(); }, + reset() { - this.dirtyData.origin = this.dirtyData.realtime; + /** + * reset 环节只需把 uuid 清空 + * 会重新进入 panel.update 周期,根据 uuid 为空的条件,把 this.dirtyData.origin 重新填充 + */ this.dirtyData.uuid = ''; }, - async change() { + async change(state) { this.pipeline = await Editor.Message.request('scene', 'change-render-pipeline', this.pipeline); - Elements.pipeline.update.call(this); - + this.updateInterface(); this.setDirtyData(); - this.dispatch('change'); - await this.preview(); + this.dispatch('change', state); + }, + + updateInterface() { + this.$.container.render(this.pipeline); + this.updateReadonly(this.$.container); + }, + + updateReadonly(element) { + if (this.asset.readonly) { + element.setAttribute('disabled', true); + } else { + element.removeAttribute('disabled'); + } }, /** @@ -242,3 +76,50 @@ exports.methods = { return isDirty; }, }; + +exports.$ = { + container: '.asset-render-pipeline', +}; + +exports.ready = function() { + this.$.container.addEventListener('change-dump', this.change.bind(this)); + + // Used to determine whether the material has been modified in isDirty() + this.dirtyData = { + uuid: '', + origin: '', + realtime: '', + }; +}; + +exports.update = async function(assetList, metaList) { + this.assetList = assetList; + this.metaList = metaList; + this.meta = this.metaList[0]; + this.asset = this.assetList[0]; + + if (assetList.length !== 1) { + this.$.container.innerText = Editor.I18n.t('ENGINE.assets.multipleWarning'); + return; + } + + if (this.dirtyData.uuid !== this.asset.uuid) { + this.dirtyData.uuid = this.asset.uuid; + this.dirtyData.origin = ''; + } + + this.pipeline = await this.query(this.asset.uuid); + + this.updateInterface(); + this.setDirtyData(); +}; + +exports.close = function() { + // Used to determine whether the material has been modified in isDirty() + this.dirtyData = { + uuid: '', + origin: '', + realtime: '', + }; +}; + diff --git a/editor/inspector/components/particle-system.js b/editor/inspector/components/particle-system.js index ac84812a222..5c64a73fd92 100644 --- a/editor/inspector/components/particle-system.js +++ b/editor/inspector/components/particle-system.js @@ -20,23 +20,22 @@ exports.template = /* html*/` - - + + - - + + - - - + + -
-
+
+ @@ -47,11 +46,37 @@ exports.template = /* html*/` - Show Bounds + - + Regenerate bounding box + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + +
@@ -59,110 +84,75 @@ exports.template = /* html*/` - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - + - - - - - - - - + + + + - - + - - - - + + + - - - - - + + + + - - - - + + + + - + @@ -178,11 +168,11 @@ exports.template = /* html*/` - + `; const excludeList = [ 'duration', 'capacity', 'loop', 'playOnAwake', 'prewarm', @@ -195,7 +185,7 @@ const excludeList = [ 'velocityOvertimeModule', 'forceOvertimeModule', 'sizeOvertimeModule', 'rotationOvertimeModule', 'colorOverLifetimeModule', 'textureAnimationModule', 'trailModule', 'renderer', 'renderCulling', 'limitVelocityOvertimeModule', 'cullingMode', - 'aabbHalfX', 'aabbHalfY', 'aabbHalfZ', + 'aabbHalfX', 'aabbHalfY', 'aabbHalfZ', 'noiseModule', ]; exports.methods = { @@ -291,15 +281,6 @@ exports.methods = { return emitEnum; }, - checkEnumInSubset(enumValue, ...subset) { - const optName = this.getEnumName(enumValue, enumValue.value); - for (const name of subset) { - if (name === optName) { - return true; - } - } - return false; - }, }; const uiElements = { @@ -331,7 +312,13 @@ const uiElements = { }, update() { const isInvalid = propUtils.isMultipleInvalid(this.dump.value.renderCulling); - this.$.resetBounds.setAttribute('disabled', isInvalid || !this.dump.value.renderCulling.value); + if (isInvalid || !this.dump.value.renderCulling.value) { + this.$.resetBounds.setAttribute('disabled', true); + } else { + if (this.$.resetBounds.hasAttribute('disabled')) { + this.$.resetBounds.removeAttribute('disabled'); + } + } }, }, uiSections: { @@ -444,7 +431,11 @@ const uiElements = { }); }, async update() { - this.$.showBounds.disabled = !this.dump.value.renderCulling.value; + if (!this.dump.value.renderCulling.value) { + this.$.showBounds.setAttribute('disabled', true); + } else if (this.$.showBounds.hasAttribute('disabled')) { + this.$.showBounds.removeAttribute('disabled'); + } const componentUUIDs = this.dump.value.uuid.values || [this.dump.value.uuid.value]; const values = await Promise.all( componentUUIDs.map( @@ -514,8 +505,8 @@ const uiElements = { }); }, /** - * - * @param {string} [eventInstigatorKey] + * + * @param {string} [eventInstigatorKey] */ update(eventInstigatorKey) { this.$.baseProps.forEach((element) => { @@ -528,35 +519,28 @@ const uiElements = { const showflag = element.getAttribute('showflag'); const disableflag = element.getAttribute('disableflag'); if (typeof showflag === 'string') { - if (showflag.startsWith('checkEnumInSubset')) { - const params = showflag.split(','); - const enumValue = this.getObjectByKey(this.dump.value, params[1]); - const subset = params.slice(2); - isShow = isShow && this.checkEnumInSubset(enumValue, ...subset); + // only update the elements relate to eventInstigator + if (eventInstigatorKey) { + if (showflag.startsWith(`!${eventInstigatorKey}`)) { + const dump = this.getObjectByKey(this.dump.value, showflag.slice(1)); + const isInvalid = propUtils.isMultipleInvalid(dump); + isShow = isShow && !isInvalid && !dump.value; + } else if (showflag.startsWith(eventInstigatorKey)) { + const dump = this.getObjectByKey(this.dump.value, showflag); + const isInvalid = propUtils.isMultipleInvalid(dump); + isShow = isShow && !isInvalid && dump.value; + } else { + return; + } } else { - // only update the elements relate to eventInstigator - if (eventInstigatorKey) { - if (showflag.startsWith(`!${eventInstigatorKey}`)) { - const dump = this.getObjectByKey(this.dump.value, showflag.slice(1)); - const isInvalid = propUtils.isMultipleInvalid(dump); - isShow = isShow && !isInvalid && !dump.value; - } else if (showflag.startsWith(eventInstigatorKey)) { - const dump = this.getObjectByKey(this.dump.value, showflag); - const isInvalid = propUtils.isMultipleInvalid(dump); - isShow = isShow && !isInvalid && dump.value; - } else { - return; - } + if (showflag.startsWith('!')) { + const dump = this.getObjectByKey(this.dump.value, showflag.slice(1)); + const isInvalid = propUtils.isMultipleInvalid(dump); + isShow = isShow && !isInvalid && !dump.value; } else { - if (showflag.startsWith('!')) { - const dump = this.getObjectByKey(this.dump.value, showflag.slice(1)); - const isInvalid = propUtils.isMultipleInvalid(dump); - isShow = isShow && !isInvalid && !dump.value; - } else { - const dump = this.getObjectByKey(this.dump.value, showflag); - const isInvalid = propUtils.isMultipleInvalid(dump); - isShow = isShow && !isInvalid && dump.value; - } + const dump = this.getObjectByKey(this.dump.value, showflag); + const isInvalid = propUtils.isMultipleInvalid(dump); + isShow = isShow && !isInvalid && dump.value; } } } else if (typeof disableflag === 'string') { @@ -568,12 +552,20 @@ const uiElements = { } if (disableflag.startsWith(`!${eventInstigatorKey}`)) { const dump = this.getObjectByKey(this.dump.value, disableflag.slice(1)); - const isInvalid = propUtils.isMultipleInvalid(dump); - contentSlot.disabled = isInvalid || !dump.value; + const isInvalid = propUtils.isMultipleInvalid(dump) || !dump.value; + if (isInvalid) { + contentSlot.setAttribute('disabled', true); + } else if (contentSlot.hasAttribute('disabled')) { + contentSlot.removeAttribute('disabled'); + } } else if (disableflag.startsWith(eventInstigatorKey)) { const dump = this.getObjectByKey(this.dump.value, disableflag); - const isInvalid = propUtils.isMultipleInvalid(dump); - contentSlot.disabled = isInvalid || !!dump.value; + const isInvalid = propUtils.isMultipleInvalid(dump) || !!dump.value; + if (isInvalid) { + contentSlot.setAttribute('disabled', true); + } else if (contentSlot.hasAttribute('disabled')) { + contentSlot.removeAttribute('disabled'); + } } else { return; } @@ -602,7 +594,11 @@ const uiElements = { if (typeof disableflag === 'string') { const contentSlot = element.querySelector('[slot=content]'); if (contentSlot) { - contentSlot.disabled = isDisable; + if (isDisable) { + contentSlot.setAttribute('disabled', true); + } else if (contentSlot.hasAttribute('disabled')) { + contentSlot.removeAttribute('disabled'); + } } } } else { @@ -640,14 +636,40 @@ const uiElements = { }); }, }, + noisePreview: { + async update() { + if (!this.dump?.value?.uuid?.values && !this.dump?.value?.uuid?.value) { return; } + let uuid = this.dump.value.uuid.values ? this.dump.value.uuid.values[0] : this.dump.value.uuid.value; + if (!uuid) { return; } + let data = await Editor.Message.request('scene', 'execute-component-method', { + uuid, + name: 'getNoisePreview', + args: [100, 100], + }); + if (data.length === 0) { return; } + + data = data.reduce((result, item) => { + const value = item * 255; + const rgba = [value, value, value, 255]; + result.push(...rgba); + return result; + }, []); + + const imageData = new ImageData(new Uint8ClampedArray(data), 100, 100); + const context = this.$.noisePreview.getContext('2d'); + context.putImageData(imageData, 0, 0); + }, + }, }; exports.$ = { customProps: '#customProps', emitFromSelect: '#emitFromSelect', showBounds: '#showBounds', resetBounds: '#resetBounds', + noisePreview: '#noisePreview', + }; -exports.ready = function() { +exports.ready = function () { for (const key in uiElements) { const element = uiElements[key]; if (typeof element.ready === 'function') { @@ -655,7 +677,7 @@ exports.ready = function() { } } }; -exports.update = function(dump) { +exports.update = function (dump) { this.dump = dump; for (const key in uiElements) { const element = uiElements[key]; diff --git a/editor/inspector/contributions/asset.js b/editor/inspector/contributions/asset.js index 516adc5b542..f9feae2fac6 100644 --- a/editor/inspector/contributions/asset.js +++ b/editor/inspector/contributions/asset.js @@ -3,8 +3,7 @@ const fs = require('fs'); const path = require('path'); const History = require('./asset-history/index'); -const showImage = ['cc.ImageAsset', 'cc.SpriteFrame', 'cc.Texture2D']; - +const showImage = ['image', 'texture', 'sprite-frame', 'gltf-mesh']; exports.listeners = {}; exports.style = fs.readFileSync(path.join(__dirname, './asset.css'), 'utf8'); @@ -240,7 +239,7 @@ const Elements = { panel.$.copy.style.display = 'none'; } - const isImage = showImage.includes(panel.asset.type); + const isImage = showImage.includes(panel.asset.importer); if (isImage) { panel.$.image.value = panel.asset.uuid; diff --git a/editor/inspector/contributions/node.js b/editor/inspector/contributions/node.js index e34b247cda3..8652f525756 100644 --- a/editor/inspector/contributions/node.js +++ b/editor/inspector/contributions/node.js @@ -154,6 +154,68 @@ exports.listeners = { console.error(error); } }, + 'preview-dump'(event) { + const panel = this; + + const target = event.target; + if (!target) { + return; + } + + const dump = event.target.dump; + if (!dump || panel.isDialoging) { + return; + } + + const { method, value: assetUuid } = event.detail; + if (method === 'confirm') { + clearTimeout(panel.previewTimeId); + + try { + panel.previewTimeId = setTimeout(() => { + for (let i = 0; i < panel.uuidList.length; i++) { + const uuid = panel.uuidList[i]; + const { path, type } = dump; + let value = dump.value; + + if (dump.values) { + value = dump.values[i]; + } + + // 预览新的值 + value.uuid = assetUuid; + + Editor.Message.send('scene', 'preview-set-property', { + uuid, + path, + dump: { + type, + value, + }, + }); + } + }, 500); + } catch (error) { + console.error(error); + } + } else if (method === 'cancel') { + clearTimeout(panel.previewTimeId); + + try { + for (let i = 0; i < panel.uuidList.length; i++) { + const uuid = panel.uuidList[i]; + const { path } = dump; + + Editor.Message.send('scene', 'cancel-preview-set-property', { + uuid, + path, + }); + } + } catch (error) { + console.error(error); + } + } + }, }; exports.template = /* html*/` @@ -940,6 +1002,10 @@ const Elements = { exports.listeners['create-dump'].call(panel, event); }); + $panel.shadowRoot.addEventListener('preview-dump', (event) => { + exports.listeners['preview-dump'].call(panel, event); + }); + $section.appendChild($panel); $section.__panels__.push($panel); $panel.dump = component; @@ -1153,7 +1219,7 @@ const Elements = { materialPanel.addEventListener('focus', () => { const children = Array.from(materialPanel.parentElement.children); - children.forEach(child => { + children.forEach((child) => { if (child === materialPanel) { child.setAttribute('focused', ''); } else { @@ -1599,8 +1665,8 @@ exports.update = async function update(uuidList, renderMap, dropConfig, typeMana const panel = this; const enginePath = path.join('editor', 'inspector', 'components'); - Object.values(renderMap).forEach(config => { - Object.values(config).forEach(renders => { + Object.values(renderMap).forEach((config) => { + Object.values(config).forEach((renders) => { renders.sort((a, b) => { return b.indexOf(enginePath) - a.indexOf(enginePath); }); diff --git a/native/cocos/3d/models/BakedSkinningModel.cpp b/native/cocos/3d/models/BakedSkinningModel.cpp index 9800cffa741..c4e099b872f 100644 --- a/native/cocos/3d/models/BakedSkinningModel.cpp +++ b/native/cocos/3d/models/BakedSkinningModel.cpp @@ -83,8 +83,8 @@ void BakedSkinningModel::bindSkeleton(Skeleton *skeleton, Node *skinningRoot, Me _jointMedium.buffer = _device->createBuffer({ gfx::BufferUsageBit::UNIFORM | gfx::BufferUsageBit::TRANSFER_DST, gfx::MemoryUsageBit::DEVICE, - pipeline::UBOSkinning::SIZE, - pipeline::UBOSkinning::SIZE, + pipeline::UBOSkinning::size, + pipeline::UBOSkinning::size, }); } } diff --git a/native/cocos/3d/models/SkinningModel.cpp b/native/cocos/3d/models/SkinningModel.cpp index 39782d27056..f558ac158a0 100644 --- a/native/cocos/3d/models/SkinningModel.cpp +++ b/native/cocos/3d/models/SkinningModel.cpp @@ -34,6 +34,9 @@ #include "scene/Pass.h" #include "scene/RenderScene.h" +const uint32_t REALTIME_JOINT_TEXTURE_WIDTH = 256; +const uint32_t REALTIME_JOINT_TEXTURE_HEIGHT = 3; + namespace { void getRelevantBuffers(ccstd::vector &outIndices, ccstd::vector &outBuffers, const ccstd::vector> &jointMaps, int32_t targetJoint) { for (int32_t i = 0; i < jointMaps.size(); i++) { @@ -51,7 +54,8 @@ void getRelevantBuffers(ccstd::vector &outIndices, ccstd::vector myPatches{{"CC_USE_SKINNING", true}}; +ccstd::vector uniformPatches{{"CC_USE_SKINNING", true}, {"CC_USE_REAL_TIME_JOINT_TEXTURE", false}}; +ccstd::vector texturePatches{{"CC_USE_SKINNING", true}, {"CC_USE_REAL_TIME_JOINT_TEXTURE", true}}; } // namespace namespace cc { @@ -60,19 +64,12 @@ SkinningModel::SkinningModel() { _type = Model::Type::SKINNING; } SkinningModel::~SkinningModel() { - for (auto *curr : _dataArray) { - delete curr; - } + releaseData(); } void SkinningModel::destroy() { bindSkeleton(nullptr, nullptr, nullptr); - if (!_buffers.empty()) { - for (gfx::Buffer *buffer : _buffers) { - CC_SAFE_DESTROY(buffer); - } - _buffers.clear(); - } + releaseData(); Super::destroy(); } @@ -84,12 +81,14 @@ void SkinningModel::bindSkeleton(Skeleton *skeleton, Node *skinningRoot, Mesh *m _joints.clear(); if (!skeleton || !skinningRoot || !mesh) return; + auto jointCount = static_cast(skeleton->getJoints().size()); + _realTimeTextureMode = pipeline::SkinningJointCapacity::jointUniformCapacity < jointCount; setTransform(skinningRoot); auto boneSpaceBounds = mesh->getBoneSpaceBounds(skeleton); const auto &jointMaps = mesh->getStruct().jointMaps; - ensureEnoughBuffers((jointMaps.has_value() && !jointMaps->empty()) ? static_cast(jointMaps->size()) : 1); + ensureEnoughBuffers((jointMaps.has_value() && !jointMaps->empty()) ? static_cast(jointMaps->size()) : 1); _bufferIndices = mesh->getJointBufferIndices(); - + initRealTimeJointTexture(); for (index_t index = 0; index < skeleton->getJoints().size(); ++index) { geometry::AABB *bound = boneSpaceBounds[index]; auto *target = skinningRoot->getChildByPath(skeleton->getJoints()[index]); @@ -129,7 +128,6 @@ void SkinningModel::updateTransform(uint32_t stamp) { Vec3 v31; Vec3 v32; for (JointInfo &jointInfo : _joints) { - const auto *bound = jointInfo.bound; auto &transform = jointInfo.transform; Mat4 worldMatrix = cc::getWorldMatrix(transform, static_cast(stamp)); jointInfo.bound->transform(worldMatrix, &ab1); @@ -151,15 +149,19 @@ void SkinningModel::updateUBOs(uint32_t stamp) { for (const JointInfo &jointInfo : _joints) { Mat4::multiply(jointInfo.transform->world, jointInfo.bindpose, &mat4); for (uint32_t buffer : jointInfo.buffers) { - uploadJointData(jointInfo.indices[bIdx] * 12, mat4, _dataArray[buffer]->data()); + uploadJointData(jointInfo.indices[bIdx] * 12, mat4, _dataArray[buffer]); bIdx++; } bIdx = 0; } - bIdx = 0; - for (const auto &buffer : _buffers) { - buffer->update(_dataArray[bIdx]->data(), buffer->getSize()); - bIdx++; + if (_realTimeTextureMode) { + updateRealTimeJointTextureBuffer(); + } else { + bIdx = 0; + for (gfx::Buffer* buffer : _buffers) { + buffer->update(_dataArray[bIdx], buffer->getSize()); + bIdx++; + } } } @@ -173,6 +175,10 @@ void SkinningModel::initSubModel(index_t idx, RenderingSubMesh *subMeshData, Mat ccstd::vector SkinningModel::getMacroPatches(index_t subModelIndex) { auto patches = Super::getMacroPatches(subModelIndex); + auto myPatches = uniformPatches; + if (_realTimeTextureMode) { + myPatches = texturePatches; + } if (!patches.empty()) { patches.reserve(myPatches.size() + patches.size()); patches.insert(std::begin(patches), std::begin(myPatches), std::end(myPatches)); @@ -191,9 +197,14 @@ void SkinningModel::uploadJointData(uint32_t base, const Mat4 &mat, float *dst) void SkinningModel::updateLocalDescriptors(index_t submodelIdx, gfx::DescriptorSet *descriptorset) { Super::updateLocalDescriptors(submodelIdx, descriptorset); - gfx::Buffer *buffer = _buffers[_bufferIndices[submodelIdx]]; - if (buffer) { - descriptorset->bindBuffer(pipeline::UBOSkinning::BINDING, buffer); + uint32_t idx = _bufferIndices[submodelIdx]; + if (!_realTimeTextureMode) { + gfx::Buffer *buffer = _buffers[idx]; + if (buffer) { + descriptorset->bindBuffer(pipeline::UBOSkinning::BINDING, buffer); + } + } else { + bindRealTimeJointTexture(idx, descriptorset); } } @@ -206,28 +217,144 @@ void SkinningModel::updateInstancedAttributes(const ccstd::vector= _buffers.size()) { - _buffers.resize(i + 1); +void SkinningModel::ensureEnoughBuffers(uint32_t count) { + if (!_buffers.empty()) { + for (gfx::Buffer *buffer : _buffers) { + CC_SAFE_DESTROY(buffer); } - - if (_buffers[i] == nullptr) { + _buffers.clear(); + } + if (!_dataArray.empty()) { + for (auto *data : _dataArray) { + CC_SAFE_DELETE_ARRAY(data); + } + _dataArray.clear(); + } + _dataArray.resize(count); + if (!_realTimeTextureMode) { + _buffers.resize(count); + uint32_t length = pipeline::UBOSkinning::count; + for (uint32_t i = 0; i < count; i++) { _buffers[i] = _device->createBuffer({ gfx::BufferUsageBit::UNIFORM | gfx::BufferUsageBit::TRANSFER_DST, gfx::MemoryUsageBit::HOST | gfx::MemoryUsageBit::DEVICE, - pipeline::UBOSkinning::SIZE, - pipeline::UBOSkinning::SIZE, + pipeline::UBOSkinning::size, + pipeline::UBOSkinning::size, }); + _dataArray[i] = new float[length]; + memset(_dataArray[i], 0, sizeof(float) * length); } + } else { + uint32_t length = 4 * REALTIME_JOINT_TEXTURE_WIDTH * REALTIME_JOINT_TEXTURE_HEIGHT; + for (uint32_t i = 0; i < count; i++) { + if (_dataArray[i] == nullptr) { + _dataArray[i] = new float[length]; + memset(_dataArray[i], 0, sizeof(float) * length); + } + } + } +} + +void SkinningModel::initRealTimeJointTexture() { + CC_SAFE_DELETE(_realTimeJointTexture); + if (!_realTimeTextureMode) return; + _realTimeJointTexture = ccnew RealTimeJointTexture; + auto *device = gfx::Device::getInstance(); + uint32_t texWidth = REALTIME_JOINT_TEXTURE_WIDTH; + uint32_t texHeight = REALTIME_JOINT_TEXTURE_HEIGHT; + gfx::Format textureFormat = gfx::Format::RGBA32F; + + gfx::FormatFeature formatFeature = device->getFormatFeatures(gfx::Format::RGBA32F); + if (!(formatFeature & gfx::FormatFeature::SAMPLED_TEXTURE)) { + textureFormat = gfx::Format::RGBA8; + texWidth = texWidth * 4; + } + uint32_t length = 4 * REALTIME_JOINT_TEXTURE_WIDTH * REALTIME_JOINT_TEXTURE_HEIGHT; + const size_t count = _dataArray.size(); + for (size_t i = 0; i < count; i++) { + gfx::TextureInfo textureInfo; + textureInfo.width = texWidth; + textureInfo.height = texHeight; + textureInfo.usage = gfx::TextureUsageBit::STORAGE | gfx::TextureUsageBit::SAMPLED | gfx::TextureUsageBit::TRANSFER_SRC | gfx::TextureUsageBit::TRANSFER_DST; + textureInfo.format = textureFormat; + IntrusivePtr texture = device->createTexture(textureInfo); + _realTimeJointTexture->textures.push_back(texture); + } + _realTimeJointTexture->buffer = new float[length]; +} + +void SkinningModel::bindRealTimeJointTexture(uint32_t idx, gfx::DescriptorSet *descriptorset) { + if (_realTimeJointTexture->textures.size() < idx + 1) return; + gfx::Texture *texture = _realTimeJointTexture->textures[idx]; + if (texture) { + gfx::SamplerInfo info{ + gfx::Filter::POINT, + gfx::Filter::POINT, + gfx::Filter::NONE, + gfx::Address::CLAMP, + gfx::Address::CLAMP, + gfx::Address::CLAMP, + }; + auto *device = gfx::Device::getInstance(); + auto *sampler = device->getSampler(info); + descriptorset->bindTexture(pipeline::REALTIMEJOINTTEXTURE::BINDING, texture); + descriptorset->bindSampler(pipeline::REALTIMEJOINTTEXTURE::BINDING, sampler); + } +} - if (i >= _dataArray.size()) { - _dataArray.resize(i + 1); +void SkinningModel::updateRealTimeJointTextureBuffer() { + uint32_t bIdx = 0; + uint32_t width = REALTIME_JOINT_TEXTURE_WIDTH; + uint32_t height = REALTIME_JOINT_TEXTURE_HEIGHT; + for (const auto &texture : _realTimeJointTexture->textures) { + auto *buffer = _realTimeJointTexture->buffer; + auto *dst = buffer; + auto *src = _dataArray[bIdx]; + uint32_t count = width; + for (uint32_t i = 0; i < count; i++) { + dst = buffer + (4 * i); + memcpy(dst, src, 16); + src = src + 4; + dst = buffer + (4 * (i + width)); + memcpy(dst, src, 16); + src = src + 4; + dst = buffer + 4 * (i + 2 * width); + memcpy(dst, src, 16); + src = src + 4; } + uint32_t buffOffset = 0; + gfx::TextureSubresLayers layer; + gfx::Offset texOffset; + gfx::Extent extent{width, height, 1}; + gfx::BufferTextureCopy region{ + buffOffset, + width, + height, + texOffset, + extent, + layer + }; + auto *device = gfx::Device::getInstance(); - if (_dataArray[i] == nullptr) { - _dataArray[i] = ccnew ccstd::array; + device->copyBuffersToTexture(reinterpret_cast(&buffer), texture, ®ion, 1); + bIdx++; + } +} + +void SkinningModel::releaseData() { + if (!_dataArray.empty()) { + for (auto* data : _dataArray) { + CC_SAFE_DELETE_ARRAY(data); } + _dataArray.clear(); + } + CC_SAFE_DELETE(_realTimeJointTexture); + if (!_buffers.empty()) { + for (gfx::Buffer *buffer : _buffers) { + CC_SAFE_DESTROY(buffer); + } + _buffers.clear(); } } + } // namespace cc diff --git a/native/cocos/3d/models/SkinningModel.h b/native/cocos/3d/models/SkinningModel.h index 154cded5e24..4bb039b4fed 100644 --- a/native/cocos/3d/models/SkinningModel.h +++ b/native/cocos/3d/models/SkinningModel.h @@ -67,12 +67,18 @@ class SkinningModel final : public MorphModel { private: static void uploadJointData(uint32_t base, const Mat4 &mat, float *dst); - void ensureEnoughBuffers(index_t count); + void ensureEnoughBuffers(uint32_t count); + void updateRealTimeJointTextureBuffer(); + void initRealTimeJointTexture(); + void bindRealTimeJointTexture(uint32_t idx, gfx::DescriptorSet *descriptorset); + void releaseData(); ccstd::vector _bufferIndices; ccstd::vector> _buffers; ccstd::vector _joints; - ccstd::vector *> _dataArray; + ccstd::vector _dataArray; + bool _realTimeTextureMode = false; + RealTimeJointTexture *_realTimeJointTexture = nullptr; CC_DISALLOW_COPY_MOVE_ASSIGN(SkinningModel); }; diff --git a/native/cocos/core/animation/SkeletalAnimationUtils.h b/native/cocos/core/animation/SkeletalAnimationUtils.h index 93a55c09b36..8c0f1db6d46 100644 --- a/native/cocos/core/animation/SkeletalAnimationUtils.h +++ b/native/cocos/core/animation/SkeletalAnimationUtils.h @@ -28,6 +28,7 @@ #include "base/Ptr.h" #include "base/RefCounted.h" #include "math/Mat4.h" +#include "renderer/gfx-base/GFXTexture.h" namespace cc { @@ -41,6 +42,17 @@ struct IJointTransform : RefCounted { IntrusivePtr parent; }; +struct RealTimeJointTexture { + ~RealTimeJointTexture() { + CC_SAFE_DELETE_ARRAY(buffer); + for (auto &texture : textures) { + texture->destroy(); + } + } + std::vector> textures; + float *buffer = nullptr; +}; + Mat4 getWorldMatrix(IJointTransform *transform, int32_t stamp); IJointTransform *getTransform(Node *node, Node *root); diff --git a/native/cocos/core/utils/Pool.h b/native/cocos/core/utils/Pool.h index 2af13081e90..928a489f88b 100644 --- a/native/cocos/core/utils/Pool.h +++ b/native/cocos/core/utils/Pool.h @@ -25,11 +25,6 @@ #pragma once -/** - * @packageDocumentation - * @module core - */ - /** * @en * A fixed-length object pool designed for general type.
diff --git a/native/cocos/renderer/pipeline/Define.cpp b/native/cocos/renderer/pipeline/Define.cpp index 0d67f34bde4..8d90ba2c680 100644 --- a/native/cocos/renderer/pipeline/Define.cpp +++ b/native/cocos/renderer/pipeline/Define.cpp @@ -266,6 +266,9 @@ const gfx::UniformBlock UBOSkinningAnimation::LAYOUT = { 1, }; +uint SkinningJointCapacity::jointUniformCapacity = 0; +uint32_t UBOSkinning::count = 0; +uint32_t UBOSkinning::size = 0; const ccstd::string UBOSkinning::NAME = "CCSkinning"; const gfx::DescriptorSetLayoutBinding UBOSkinning::DESCRIPTOR = { UBOSkinning::BINDING, @@ -274,15 +277,20 @@ const gfx::DescriptorSetLayoutBinding UBOSkinning::DESCRIPTOR = { gfx::ShaderStageFlagBit::VERTEX, {}, }; -const gfx::UniformBlock UBOSkinning::LAYOUT = { +gfx::UniformBlock UBOSkinning::layout = { localSet, UBOSkinning::BINDING, UBOSkinning::NAME, { - {"cc_joints", gfx::Type::FLOAT4, JOINT_UNIFORM_CAPACITY * 3}, + {"cc_joints", gfx::Type::FLOAT4, 0}, }, 1, }; +void UBOSkinning::initLayout (uint32_t capacity) { + UBOSkinning::count = capacity * 12; + UBOSkinning::size = UBOSkinning::count * sizeof(float); + UBOSkinning::layout.members[0].count = capacity * 3; +} const uint32_t UBOMorph::COUNT_BASE_4_BYTES = static_cast(4 * std::ceil(UBOMorph::MAX_MORPH_TARGET_COUNT / 4) + 4); const uint32_t UBOMorph::SIZE = UBOMorph::COUNT_BASE_4_BYTES * 4; @@ -402,6 +410,22 @@ const gfx::UniformSamplerTexture JOINTTEXTURE::LAYOUT = { 1, }; +const ccstd::string REALTIMEJOINTTEXTURE::NAME = "cc_realtimeJoint"; +const gfx::DescriptorSetLayoutBinding REALTIMEJOINTTEXTURE::DESCRIPTOR = { + REALTIMEJOINTTEXTURE::BINDING, + gfx::DescriptorType::SAMPLER_TEXTURE, + 1, + gfx::ShaderStageFlagBit::VERTEX, + {}, +}; +const gfx::UniformSamplerTexture REALTIMEJOINTTEXTURE::LAYOUT = { + localSet, + REALTIMEJOINTTEXTURE::BINDING, + REALTIMEJOINTTEXTURE::NAME, + gfx::Type::SAMPLER2D, + 1, +}; + const ccstd::string POSITIONMORPH::NAME = "cc_PositionDisplacements"; const gfx::DescriptorSetLayoutBinding POSITIONMORPH::DESCRIPTOR = { POSITIONMORPH::BINDING, diff --git a/native/cocos/renderer/pipeline/Define.h b/native/cocos/renderer/pipeline/Define.h index 0711a1ebbe4..dc0dbeea9af 100644 --- a/native/cocos/renderer/pipeline/Define.h +++ b/native/cocos/renderer/pipeline/Define.h @@ -48,7 +48,10 @@ class RenderFlow; // Skinning models with number of bones more than this capacity will be automatically switched to texture skinning. // But still, you can tweak this for your own need by changing the number below // and the JOINT_UNIFORM_CAPACITY macro in cc-skinning shader header. -constexpr int JOINT_UNIFORM_CAPACITY = 30; +class CC_DLL SkinningJointCapacity { +public: + static uint32_t jointUniformCapacity; +}; constexpr float SHADOW_CAMERA_MAX_FAR = 2000.0F; const float COEFFICIENT_OF_EXPANSION = 2.0F * sqrtf(3.0F); @@ -341,13 +344,13 @@ struct CC_DLL UBOSkinningAnimation { }; struct CC_DLL UBOSkinning { - static constexpr uint32_t JOINTS_OFFSET = 0; - static constexpr uint32_t COUNT = UBOSkinning::JOINTS_OFFSET + JOINT_UNIFORM_CAPACITY * 12; - static constexpr uint32_t SIZE = UBOSkinning::COUNT * 4; + static uint32_t count; + static uint32_t size; static constexpr uint32_t BINDING = static_cast(ModelLocalBindings::UBO_SKINNING_TEXTURE); static const gfx::DescriptorSetLayoutBinding DESCRIPTOR; - static const gfx::UniformBlock LAYOUT; + static gfx::UniformBlock layout; static const ccstd::string NAME; + static void initLayout (uint capacity); }; struct CC_DLL UBOMorph { @@ -554,6 +557,13 @@ struct CC_DLL JOINTTEXTURE { static const ccstd::string NAME; }; +struct CC_DLL REALTIMEJOINTTEXTURE { + static constexpr uint BINDING = static_cast(ModelLocalBindings::SAMPLER_JOINTS); + static const gfx::DescriptorSetLayoutBinding DESCRIPTOR; + static const gfx::UniformSamplerTexture LAYOUT; + static const ccstd::string NAME; +}; + struct CC_DLL POSITIONMORPH { static constexpr uint32_t BINDING = static_cast(ModelLocalBindings::SAMPLER_MORPH_POSITION); static const gfx::DescriptorSetLayoutBinding DESCRIPTOR; diff --git a/native/cocos/renderer/pipeline/GlobalDescriptorSetManager.cpp b/native/cocos/renderer/pipeline/GlobalDescriptorSetManager.cpp index edc6a5f9d1f..0e1f6a3680a 100644 --- a/native/cocos/renderer/pipeline/GlobalDescriptorSetManager.cpp +++ b/native/cocos/renderer/pipeline/GlobalDescriptorSetManager.cpp @@ -52,6 +52,12 @@ void GlobalDSManager::activate(gfx::Device *device) { gfx::Address::CLAMP, }); + //tips: for compatibility with old version, when maxVertexUniformVectors is 128, maxJoints = 30 + uint maxJoints = (_device->getCapabilities().maxVertexUniformVectors - 38) / 3; + maxJoints = maxJoints < 256 ? maxJoints : 256; + SkinningJointCapacity::jointUniformCapacity = maxJoints; + UBOSkinning::initLayout(maxJoints); + setDescriptorSetLayout(); _descriptorSetLayout = device->createDescriptorSetLayout({globalDescriptorSetLayout.bindings}); _globalDescriptorSet = device->createDescriptorSet({_descriptorSetLayout}); @@ -184,7 +190,7 @@ void GlobalDSManager::setDescriptorSetLayout() { localDescriptorSetLayout.bindings[UBOSkinningTexture::BINDING] = UBOSkinningTexture::DESCRIPTOR; localDescriptorSetLayout.blocks[UBOSkinningAnimation::NAME] = UBOSkinningAnimation::LAYOUT; localDescriptorSetLayout.bindings[UBOSkinningAnimation::BINDING] = UBOSkinningAnimation::DESCRIPTOR; - localDescriptorSetLayout.blocks[UBOSkinning::NAME] = UBOSkinning::LAYOUT; + localDescriptorSetLayout.blocks[UBOSkinning::NAME] = UBOSkinning::layout; localDescriptorSetLayout.bindings[UBOSkinning::BINDING] = UBOSkinning::DESCRIPTOR; localDescriptorSetLayout.blocks[UBOMorph::NAME] = UBOMorph::LAYOUT; localDescriptorSetLayout.bindings[UBOMorph::BINDING] = UBOMorph::DESCRIPTOR; @@ -192,6 +198,8 @@ void GlobalDSManager::setDescriptorSetLayout() { localDescriptorSetLayout.bindings[UBOUILocal::BINDING] = UBOUILocal::DESCRIPTOR; localDescriptorSetLayout.samplers[JOINTTEXTURE::NAME] = JOINTTEXTURE::LAYOUT; localDescriptorSetLayout.bindings[JOINTTEXTURE::BINDING] = JOINTTEXTURE::DESCRIPTOR; + localDescriptorSetLayout.samplers[REALTIMEJOINTTEXTURE::NAME] = REALTIMEJOINTTEXTURE::LAYOUT; + localDescriptorSetLayout.bindings[REALTIMEJOINTTEXTURE::BINDING] = REALTIMEJOINTTEXTURE::DESCRIPTOR; localDescriptorSetLayout.samplers[POSITIONMORPH::NAME] = POSITIONMORPH::LAYOUT; localDescriptorSetLayout.bindings[POSITIONMORPH::BINDING] = POSITIONMORPH::DESCRIPTOR; localDescriptorSetLayout.samplers[NORMALMORPH::NAME] = NORMALMORPH::LAYOUT; diff --git a/native/cocos/renderer/pipeline/RenderPipeline.cpp b/native/cocos/renderer/pipeline/RenderPipeline.cpp index dadc13790e7..ecddf48c379 100644 --- a/native/cocos/renderer/pipeline/RenderPipeline.cpp +++ b/native/cocos/renderer/pipeline/RenderPipeline.cpp @@ -318,12 +318,14 @@ void RenderPipeline::generateConstantMacros() { #define CC_DEVICE_CAN_BENEFIT_FROM_INPUT_ATTACHMENT %d #define CC_PLATFORM_ANDROID_AND_WEBGL 0 #define CC_ENABLE_WEBGL_HIGHP_STRUCT_VALUES 0 +#define CC_JOINT_UNIFORM_CAPACITY %d )", hasAnyFlags(_device->getFormatFeatures(gfx::Format::RGBA32F), gfx::FormatFeature::RENDER_TARGET | gfx::FormatFeature::SAMPLED_TEXTURE), _clusterEnabled ? 1 : 0, _device->getCapabilities().maxVertexUniformVectors, _device->getCapabilities().maxFragmentUniformVectors, - _device->hasFeature(gfx::Feature::INPUT_ATTACHMENT_BENEFIT)); + _device->hasFeature(gfx::Feature::INPUT_ATTACHMENT_BENEFIT), + SkinningJointCapacity::jointUniformCapacity); } gfx::DescriptorSetLayout *RenderPipeline::getDescriptorSetLayout() const { return _globalDSManager->getDescriptorSetLayout(); } diff --git a/tests/animation/embedded-player/embedded-animation-clip-player.test.ts b/tests/animation/embedded-player/embedded-animation-clip-player.test.ts new file mode 100644 index 00000000000..470086da324 --- /dev/null +++ b/tests/animation/embedded-player/embedded-animation-clip-player.test.ts @@ -0,0 +1,4 @@ + +test('Animation clip embedded player test', () => { + +}); \ No newline at end of file diff --git a/tests/animation/embedded-player/embedded-particle-system-player.test.ts b/tests/animation/embedded-player/embedded-particle-system-player.test.ts new file mode 100644 index 00000000000..8efc55a6498 --- /dev/null +++ b/tests/animation/embedded-player/embedded-particle-system-player.test.ts @@ -0,0 +1,50 @@ +import { Node, warn } from "../../../cocos/core"; +import { EmbeddedPlayer } from "../../../cocos/core/animation/embedded-player/embedded-player"; +import { EmbeddedParticleSystemPlayable } from "../../../cocos/core/animation/embedded-player/embedded-particle-system-player"; +import { EmbeddedPlayerHostMock } from "./util"; +import { ParticleSystem } from "../../../cocos/particle"; +import { captureWarns } from "../../utils/log-capture"; + +test('Particle system embedded player test', () => { + const rootNode = new Node('Root Node'); + const nodeThatDoesNotIncludeAParticleSystem = new Node('Does Not Include a Particle System'); + rootNode.addChild(nodeThatDoesNotIncludeAParticleSystem); + const particleSystemNode = new Node('Particle System Node'); + particleSystemNode.addComponent(ParticleSystem); + rootNode.addChild(particleSystemNode); + + { + const embeddedPlayer = new EmbeddedPlayer(); + const player = embeddedPlayer.playable = new EmbeddedParticleSystemPlayable(); + player.path = 'Non-existing node'; + + const warnWatcher = captureWarns(); + const host = new EmbeddedPlayerHostMock(rootNode, embeddedPlayer, 1.3); + expect(warnWatcher.captured).toHaveLength(1); + expect(warnWatcher.captured[0][0]).toMatch(/Non-existing node/); + warnWatcher.stop(); + } + + { + const embeddedPlayer = new EmbeddedPlayer(); + const player = embeddedPlayer.playable = new EmbeddedParticleSystemPlayable(); + player.path = 'Does Not Include a Particle System'; + + const warnWatcher = captureWarns(); + const host = new EmbeddedPlayerHostMock(rootNode, embeddedPlayer, 1.3); + expect(warnWatcher.captured).toHaveLength(1); + expect(warnWatcher.captured[0][0]).toMatch(/Does Not Include a Particle System/); + warnWatcher.stop(); + } + + { + const embeddedPlayer = new EmbeddedPlayer(); + const player = embeddedPlayer.playable = new EmbeddedParticleSystemPlayable(); + player.path = 'Particle System Node'; + const warnWatcher = captureWarns(); + const host = new EmbeddedPlayerHostMock(rootNode, embeddedPlayer, 1.3); + expect(host.randomAccessible).toBe(false); + expect(warnWatcher.captured).toHaveLength(0); + warnWatcher.stop(); + } +}); \ No newline at end of file diff --git a/tests/animation/embedded-player/genernal-embedded-player.test.ts b/tests/animation/embedded-player/genernal-embedded-player.test.ts new file mode 100644 index 00000000000..3ad2b20ee93 --- /dev/null +++ b/tests/animation/embedded-player/genernal-embedded-player.test.ts @@ -0,0 +1,345 @@ +import { Node } from "../../../cocos/core"; +import { addEmbeddedPlayerTag, AnimationClip } from "../../../cocos/core/animation/animation-clip"; +import { AnimationState } from "../../../cocos/core/animation/animation-state"; +import { EmbeddedPlayer, EmbeddedPlayable, EmbeddedPlayableState } from "../../../cocos/core/animation/embedded-player/embedded-player"; +import { AnimationClipHostEmbeddedPlayerMock } from "./util"; + +describe('General embedded player test', () => { + test('Default', () => { + const embeddedPlayer = new EmbeddedPlayer(); + expect(embeddedPlayer.begin).toBe(0.0); + expect(embeddedPlayer.end).toBe(0.0); + expect(embeddedPlayer.reconciledSpeed).toBe(false); + expect(embeddedPlayer.playable).toBe(null); + }); + + describe('Embedded player behaviors during animation clip evaluation', () => { + test('Embedded player\'s play() is called when and only when host evaluating', () => { + const embeddedPlayer = new EmbeddedPlayer(); + const embeddedPlayerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(false); + embeddedPlayer.begin = 0.3; + embeddedPlayer.end = 0.7; + const node = new Node(); + const host = new AnimationClipHostEmbeddedPlayerMock(node, embeddedPlayer, 1.2); + + host.play(0.32); // The time has arrived in embedded player's interval, but it has not been evaluated. + expect(embeddedPlayerMock.playMock).toHaveBeenCalledTimes(0); + + host.evaluateAt(0.33); // Enter the region + expect(embeddedPlayerMock.playMock).toHaveBeenCalledTimes(1); + expect(embeddedPlayerMock.playMock.mock.calls[0][0]).toBeCloseTo(0.03); + embeddedPlayerMock.playMock.mockClear(); + + embeddedPlayerMock.zeroCheck(); + }); + + test('Embedded player\'s stop() is called when host evaluating outside the embedded player\'s interval', () => { + const embeddedPlayer = new EmbeddedPlayer(); + const embeddedPlayerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(false); + embeddedPlayer.begin = 0.3; + embeddedPlayer.end = 0.7; + const node = new Node(); + const host = new AnimationClipHostEmbeddedPlayerMock(node, embeddedPlayer, 1.2); + + host.evaluateAt(0.33); // Enter the region + expect(embeddedPlayerMock.playMock).toHaveBeenCalledTimes(1); + expect(embeddedPlayerMock.playMock.mock.calls[0][0]).toBeCloseTo(0.03); + embeddedPlayerMock.playMock.mockClear(); + + host.evaluateAt(0.6); // Evaluate at the middle, nothing happened + + host.evaluateAt(0.75); // Evaluate outside the interval, call `stop()` + expect(embeddedPlayerMock.stopMock).toHaveBeenCalledTimes(1); + embeddedPlayerMock.stopMock.mockClear(); + + embeddedPlayerMock.zeroCheck(); + }); + + test('Embedded player\'s stop() is also called when host stops', () => { + const embeddedPlayer = new EmbeddedPlayer(); + const embeddedPlayerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(false); + embeddedPlayer.begin = 0.3; + embeddedPlayer.end = 0.7; + const node = new Node(); + const host = new AnimationClipHostEmbeddedPlayerMock(node, embeddedPlayer, 1.2); + + host.evaluateAt(0.33); // Enter the region + expect(embeddedPlayerMock.playMock).toHaveBeenCalledTimes(1); + expect(embeddedPlayerMock.playMock.mock.calls[0][0]).toBeCloseTo(0.03); + embeddedPlayerMock.playMock.mockClear(); + + host.stop(); // Evaluate outside the interval, call `stop()` + expect(embeddedPlayerMock.stopMock).toHaveBeenCalledTimes(1); + embeddedPlayerMock.stopMock.mockClear(); + + embeddedPlayerMock.zeroCheck(); + }); + + test('Embedded player\'s play() is triggered every time it reentered', () => { + const embeddedPlayer = new EmbeddedPlayer(); + const embeddedPlayerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(false); + embeddedPlayer.begin = 0.3; + embeddedPlayer.end = 0.7; + const node = new Node(); + const host = new AnimationClipHostEmbeddedPlayerMock(node, embeddedPlayer, 1.2); + + host.evaluateAt(0.33); // Enter the region + expect(embeddedPlayerMock.playMock).toHaveBeenCalledTimes(1); + expect(embeddedPlayerMock.playMock.mock.calls[0][0]).toBeCloseTo(0.03); + embeddedPlayerMock.playMock.mockClear(); + + host.evaluateAt(0.8); // Evaluate outside the interval + expect(embeddedPlayerMock.stopMock).toHaveBeenCalledTimes(1); + embeddedPlayerMock.stopMock.mockClear(); + + host.evaluateAt(0.42); // Again enter the region + expect(embeddedPlayerMock.playMock).toHaveBeenCalledTimes(1); + expect(embeddedPlayerMock.playMock.mock.calls[0][0]).toBeCloseTo(0.12); + embeddedPlayerMock.playMock.mockClear(); + + embeddedPlayerMock.zeroCheck(); + }); + + test('Embedded player\'s pause() is called when host pauses in the embedded players\'s interval', () => { + const embeddedPlayer = new EmbeddedPlayer(); + const embeddedPlayerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(false); + embeddedPlayer.begin = 0.3; + embeddedPlayer.end = 0.7; + const node = new Node(); + const host = new AnimationClipHostEmbeddedPlayerMock(node, embeddedPlayer, 1.2); + + host.play(0.13); + host.evaluateAt(0.13); + host.pause(0.14); // Pause at the outside before the first time the embedded player entered. + expect(embeddedPlayerMock.pauseMock).not.toHaveBeenCalled(); + + host.play(0.32); + host.evaluateAt(0.32); // Enter the embedded player + embeddedPlayerMock.playMock.mockClear(); + + expect(embeddedPlayerMock.pauseMock).not.toHaveBeenCalled(); + host.pause(0.33); + expect(embeddedPlayerMock.pauseMock).toHaveBeenCalledTimes(1); + embeddedPlayerMock.pauseMock.mockClear(); + + host.play(0.4); + embeddedPlayerMock.playMock.mockClear(); + host.evaluateAt(0.87); // Exit the embedded player + embeddedPlayerMock.stopMock.mockClear(); + + host.pause(0.9); // Pause at the outside + expect(embeddedPlayerMock.pauseMock).not.toHaveBeenCalled(); + + embeddedPlayerMock.zeroCheck(); + }); + + describe('Host resuming', () => { + type HostResumingInput = [ + title: string, + // Input: whether the host resumes at the same time when it paused. + hostResumeAtSameTime: boolean, + // Input: whether the embedded player is random accessible. + randomAccessible: boolean, + // The result: whether the embedded player will be resumed or stopped. + embeddedPlayerResumable: boolean, + ]; + test.each([ + [ + 'For non-random-accessible embedded players, if host resume at same time, the embedded players will be resumed, too', + true, + false, + true, + ], + [ + 'For non-random-accessible embedded players, embedded players would be stopped if host resume at different time ', + false, + false, + false, + ], + [ + 'For random-accessible embedded players, embedded players would be stopped even if host resume at different time ', + false, + true, + true, + ], + ] as ReadonlyArray)(`%s`, (_title, hostResumeAtSameTime, embeddedPlayerRandomAccessible, embeddedPlayerResumable) => { + const embeddedPlayer = new EmbeddedPlayer(); + const embeddedPlayerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(embeddedPlayerRandomAccessible); + embeddedPlayer.begin = 0.3; + embeddedPlayer.end = 0.7; + const node = new Node(); + const host = new AnimationClipHostEmbeddedPlayerMock(node, embeddedPlayer, 1.2); + + host.play(0.0); + + host.evaluateAt(0.33); // Enter the region + expect(embeddedPlayerMock.playMock).toHaveBeenCalledTimes(1); + expect(embeddedPlayerMock.playMock.mock.calls[0][0]).toBeCloseTo(0.03); + embeddedPlayerMock.playMock.mockClear(); + + host.pause(0.4); + expect(embeddedPlayerMock.pauseMock).toHaveBeenCalledTimes(1); + embeddedPlayerMock.pauseMock.mockClear(); + + const hostResumeTime = hostResumeAtSameTime + ? 0.4 + : 0.4 + 0.02; // Resume at a different time + host.play(hostResumeTime); + + if (embeddedPlayerResumable) { + expect(embeddedPlayerMock.playMock).toHaveBeenCalledTimes(1); + expect(embeddedPlayerMock.playMock.mock.calls[0][0]).toBeCloseTo(hostResumeTime - 0.3); + embeddedPlayerMock.playMock.mockClear(); + } else { + expect(embeddedPlayerMock.stopMock).toHaveBeenCalledTimes(1); + embeddedPlayerMock.stopMock.mockClear(); + } + + embeddedPlayerMock.zeroCheck(); + }); + }); + + test('Embedded player\'s setSpeed() is called if it has "reconciledSpeed" set to true', () => { + const embeddedPlayer = new EmbeddedPlayer(); + const embeddedPlayerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(false); + embeddedPlayer.begin = 0.3; + embeddedPlayer.end = 0.7; + embeddedPlayer.reconciledSpeed = true; + const node = new Node(); + const host = new AnimationClipHostEmbeddedPlayerMock(node, embeddedPlayer, 1.2); + + host.setSpeed(1.9); + expect(embeddedPlayerMock.setSpeedMock).toBeCalledTimes(1); + expect(embeddedPlayerMock.setSpeedMock.mock.calls[0][0]).toBeCloseTo(1.9); + embeddedPlayerMock.setSpeedMock.mockClear(); + + embeddedPlayerMock.zeroCheck(); + }); + + test('Embedded player\'s setSpeed() is not called if it has "reconciledSpeed" set to false', () => { + const embeddedPlayer = new EmbeddedPlayer(); + const embeddedPlayerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(false); + embeddedPlayer.begin = 0.3; + embeddedPlayer.end = 0.7; + embeddedPlayer.reconciledSpeed = false; + const node = new Node(); + const host = new AnimationClipHostEmbeddedPlayerMock(node, embeddedPlayer, 1.2); + + host.setSpeed(1.9); + expect(embeddedPlayerMock.setSpeedMock).not.toBeCalled(); + + embeddedPlayerMock.zeroCheck(); + }); + + test('Broadcasting of animation state\'s speed', () => { + const clip = new AnimationClip(); + clip.speed = 0.6; + const embeddedPlayer = new EmbeddedPlayer(); + embeddedPlayer.reconciledSpeed = true; + const playerMock = embeddedPlayer.playable = new EmbeddedPlayerMock(); + clip[addEmbeddedPlayerTag](embeddedPlayer); + + const animationState = new AnimationState(clip); + const node = new Node(); + expect(playerMock.setSpeedMock).not.toBeCalled(); + + animationState.initialize(node); + expect(playerMock.setSpeedMock).toBeCalledTimes(1); + expect(playerMock.setSpeedMock.mock.calls[0][0]).toBe(0.6); + playerMock.setSpeedMock.mockClear(); + + animationState.speed = 0.8; + expect(playerMock.setSpeedMock).toBeCalledTimes(1); + expect(playerMock.setSpeedMock.mock.calls[0][0]).toBe(0.8); + playerMock.setSpeedMock.mockClear(); + }); + }); +}); + +class EmbeddedPlayerMock extends EmbeddedPlayable { + constructor( private _randomAccess = false) { + super(); + } + + get destroyMock() { + return this._destroyMock; + } + + get playMock() { + return this._playMock; + } + + get pauseMock () { + return this._pauseMock; + } + + get stopMock () { + return this._stopMock; + } + + get setSpeedMock() { + return this._setSpeedMock; + } + + public zeroCheck() { + for (const mock of [ + this._destroyMock, + this._playMock, + this._pauseMock, + this._stopMock, + this._setSpeedMock, + ]) { + expect(mock).toBeCalledTimes(0); + } + } + + instantiate() { + return new InstantiatedEmbeddedPlayerMock( + this._randomAccess, + this._destroyMock, + this._playMock, + this._pauseMock, + this._stopMock, + this._setSpeedMock, + ); + } + + private _destroyMock = jest.fn(); + private _playMock = jest.fn(); + private _pauseMock = jest.fn(); + private _stopMock = jest.fn(); + private _setSpeedMock = jest.fn(); +} + +class InstantiatedEmbeddedPlayerMock extends EmbeddedPlayableState { + constructor( + randomAccess: boolean, + private _destroyMock: jest.Mock, + private _playMock: jest.Mock, + private _pauseMock: jest.Mock, + private _stopMock: jest.Mock, + private _setSpeedMock: jest.Mock, + ) { + super(randomAccess); + } + + public destroy(...args: Parameters): void { + this._destroyMock(...args); + } + + public play(...args: Parameters): void { + this._playMock(...args); + } + + public pause(...args: Parameters): void { + this._pauseMock(...args); + } + + public stop(...args: Parameters): void { + this._stopMock(...args); + } + + public setSpeed(...args: Parameters): void { + this._setSpeedMock(...args); + } +} \ No newline at end of file diff --git a/tests/animation/embedded-player/util.ts b/tests/animation/embedded-player/util.ts new file mode 100644 index 00000000000..c985dab5a00 --- /dev/null +++ b/tests/animation/embedded-player/util.ts @@ -0,0 +1,65 @@ +import { Node } from "../../../cocos/core"; +import { addEmbeddedPlayerTag, AnimationClip } from "../../../cocos/core/animation/animation-clip"; +import { EmbeddedPlayableState } from "../../../cocos/core/animation/embedded-player/embedded-player"; +import { EmbeddedPlayer } from "../../../editor/exports/embedded-player"; + +export class EmbeddedPlayerHostMock { + constructor(root: Node, private _embeddedPlayer: EmbeddedPlayer, _hostDuration: number) { + const instantiatedPlayer = this._embeddedPlayer.playable.instantiate(root); + this._instantiatedPlayer = instantiatedPlayer; + } + + get wellInstantiated() { + return !!this._instantiatedPlayer; + } + + get randomAccessible() { + return this._instantiatedPlayer.randomAccess; + } + + public play(time: number) { + this._instantiatedPlayer.play(time); + } + + public stop() { + this._instantiatedPlayer.stop(); + } + + public setSpeed(speed: number) { + this._instantiatedPlayer.setSpeed(speed); + } + + private _instantiatedPlayer: EmbeddedPlayableState | null; +} + +export class AnimationClipHostEmbeddedPlayerMock { + constructor(_root: Node, embeddedPlayer: EmbeddedPlayer, hostDuration: number) { + const animationClip = new AnimationClip(); + animationClip.duration = hostDuration; + animationClip[addEmbeddedPlayerTag](embeddedPlayer); + const evaluator = animationClip.createEvaluator({ target: _root }); + this._animationEvaluator = evaluator; + } + + public play(time: number) { + this._animationEvaluator.notifyHostPlay(time); + } + + public pause(time: number) { + this._animationEvaluator.notifyHostPause(time); + } + + public stop() { + this._animationEvaluator.notifyHostStop(); + } + + public setSpeed(speed: number) { + this._animationEvaluator.notifyHostSpeedChanged(speed); + } + + public evaluateAt(time: number) { + this._animationEvaluator.evaluate(time); + } + + private _animationEvaluator: ReturnType; +} \ No newline at end of file diff --git a/tests/particle/stop-emitting.test.ts b/tests/particle/stop-emitting.test.ts new file mode 100644 index 00000000000..e15f08f98fd --- /dev/null +++ b/tests/particle/stop-emitting.test.ts @@ -0,0 +1,31 @@ +import { director, game, Node, Scene } from "../../cocos/core"; +import { ParticleSystem } from "../../exports/particle"; + +test('stop emitting', () => { + const scene = new Scene('test-scene'); + director.runSceneImmediate(scene); + const node = new Node(); + scene.addChild(node); + game.step(); + const particleSystem = node.addComponent(ParticleSystem) as ParticleSystem; + particleSystem.capacity = 1000; + particleSystem.startLifetime.constant = 5; + particleSystem.rateOverTime.constant = 100; + particleSystem.play(); + for (let i = 0; i < 60; i++) { + game.step(); + } + expect(particleSystem.getParticleCount()).toBe(100); + particleSystem.stopEmitting(); + for (let i = 0; i < 60; i++) { + game.step(); + } + expect(particleSystem.getParticleCount()).toBe(100); + particleSystem.play(); + for (let i = 0; i < 60; i++) { + game.step(); + } + expect(particleSystem.getParticleCount()).toBe(200); + particleSystem.stop(); + expect(particleSystem.getParticleCount()).toBe(0); +}); \ No newline at end of file