补充某些必要的文件

This commit is contained in:
SmallMain
2022-06-25 11:52:00 +08:00
parent 4ecc470f86
commit 03533b046c
2869 changed files with 1345388 additions and 2 deletions

View File

@@ -0,0 +1,20 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
#if USE_ALPHA_TEST
uniform ALPHA_TEST {
float alphaThreshold;
};
#endif
void ALPHA_TEST (in vec4 color) {
#if USE_ALPHA_TEST
if (color.a < alphaThreshold) discard;
#endif
}
void ALPHA_TEST (in float alpha) {
#if USE_ALPHA_TEST
if (alpha < alphaThreshold) discard;
#endif
}

View File

@@ -0,0 +1,23 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
// have to specify precisions explicitly
// if shared among stages with different precisions
#pragma builtin(global)
uniform CCGlobal {
mat4 cc_matView; // view matrix
mat4 cc_matViewInv; // inverse view matrix
mat4 cc_matProj; // projection matrix
mat4 cc_matProjInv; // inverse projection matrix
mat4 cc_matViewProj; // view-projection matrix
mat4 cc_matViewProjInv; // inverse view-projection matrix
vec4 cc_cameraPos; // xyz: camera position
vec4 cc_time; // x: global time since started in seconds, y: delta time for current frame, z: total frames since started
mediump vec4 cc_screenSize; // xy: screen size, zw: inverse screen size
mediump vec4 cc_screenScale; // xy: screen scale, zw: inverse screen scale
// mediump vec4 cc_nativeSize; // xy: shading size, zw: inverse shading size
// mediump vec4 cc_exposure; // x: exposure, y: inverse exposure, z: HDR flag, w: exposure scale
// mediump vec4 cc_mainLitDir; // xyz: main direcitonal light direction
// mediump vec4 cc_mainLitColor; // xyz: main direcitonal light color, w: intensity
// mediump vec4 cc_ambientSky; //xyz: sky illumination color, w: intensity
// mediump vec4 cc_ambientGround; // xyz: ground albedo color, w: envmap LOD
};

View File

@@ -0,0 +1,110 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
// TODO: lights uniform should move back to cc-global
#include <shadow>
#define CC_MAX_LIGHTS 4
#if CC_NUM_LIGHTS > 0
// directional lights
#pragma builtin(global)
uniform CCLIGHTS {
vec4 cc_lightPositionAndRange[CC_MAX_LIGHTS]; // xyz range
vec4 cc_lightDirection[CC_MAX_LIGHTS]; // xyz spotAngle
vec4 cc_lightColor[CC_MAX_LIGHTS]; // xyz spotExp
};
#endif
struct LightInfo {
vec3 lightDir;
vec3 radiance;
vec4 lightColor;
};
// directional light
LightInfo computeDirectionalLighting(
vec4 lightDirection,
vec4 lightColor
) {
LightInfo ret;
ret.lightDir = -normalize(lightDirection.xyz);
ret.radiance = lightColor.rgb;
ret.lightColor = lightColor;
return ret;
}
// point light
LightInfo computePointLighting(
vec3 worldPosition,
vec4 lightPositionAndRange,
vec4 lightColor
) {
LightInfo ret;
vec3 lightDir = lightPositionAndRange.xyz - worldPosition;
float attenuation = max(0., 1.0 - length(lightDir) / lightPositionAndRange.w);
ret.lightDir = normalize(lightDir);
ret.radiance = lightColor.rgb * attenuation;
ret.lightColor = lightColor;
return ret;
}
// spot light
LightInfo computeSpotLighting(
vec3 worldPosition,
vec4 lightPositionAndRange,
vec4 lightDirection,
vec4 lightColor
) {
LightInfo ret;
vec3 lightDir = lightPositionAndRange.xyz - worldPosition;
float attenuation = max(0., 1.0 - length(lightDir) / lightPositionAndRange.w);
lightDir = normalize(lightDir);
float cosConeAngle = max(0., dot(lightDirection.xyz, -lightDir));
cosConeAngle = cosConeAngle < lightDirection.w ? 0. : cosConeAngle;
cosConeAngle = pow(cosConeAngle, lightColor.w);
ret.lightDir = lightDir;
ret.radiance = lightColor.rgb * attenuation * cosConeAngle;
ret.lightColor = lightColor;
return ret;
}
struct Lighting {
vec3 diffuse;
vec3 specular;
};
#define CC_CALC_LIGHT(index, surface, result, lightFunc, ambientFunc) \
#if CC_NUM_LIGHTS > index \
#if CC_LIGHT_##index##_TYPE == 3 \
result.diffuse += ambientFunc(s, cc_lightColor[index]); \
#else \
LightInfo info##index; \
#if CC_LIGHT_##index##_TYPE == 0 \
info##index = computeDirectionalLighting(cc_lightDirection[index], cc_lightColor[index]); \
#elif CC_LIGHT_##index##_TYPE == 1 \
info##index = computePointLighting(s.position, cc_lightPositionAndRange[index], cc_lightColor[index]); \
#elif CC_LIGHT_##index##_TYPE == 2 \
info##index = computeSpotLighting(s.position, cc_lightPositionAndRange[index], cc_lightDirection[index], cc_lightColor[index]); \
#endif \
\
Lighting result##index = lightFunc(surface, info##index); \
CC_CALC_SHADOW(index, result##index) \
result.diffuse += result##index.diffuse; \
result.specular += result##index.specular; \
#endif \
#endif
#define CC_CALC_LIGHTS(surface, result, lightFunc, ambientFunc) \
result.diffuse = vec3(0, 0, 0); \
result.specular = vec3(0, 0, 0); \
\
CC_CALC_LIGHT(0, surface, result, lightFunc, ambientFunc) \
CC_CALC_LIGHT(1, surface, result, lightFunc, ambientFunc) \
CC_CALC_LIGHT(2, surface, result, lightFunc, ambientFunc) \
CC_CALC_LIGHT(3, surface, result, lightFunc, ambientFunc)

View File

@@ -0,0 +1,7 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
#pragma builtin(local)
uniform CCLocal {
mat4 cc_matWorld;
mat4 cc_matWorldIT;
};

View File

@@ -0,0 +1,12 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
// common module
// constant value
#define PI 3.14159265359
#define PI2 6.28318530718
#define EPSILON 1e-6
#define LOG2 1.442695
// common function
#define saturate(a) clamp( a, 0.0, 1.0 )

View File

@@ -0,0 +1,7 @@
// Copyright (c) 2017-2019 Xiamen Yaji Software Co., Ltd.
// #define SRGBToLinear(gamma) pow(gamma, vec3(2.2))
#define SRGBToLinear(gamma) (gamma * gamma)
// #define LinearToSRGB(linear) pow(linear, vec3(0.454545))
#define LinearToSRGB(linear) sqrt(linear)

View File

@@ -0,0 +1,76 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
#include <skinning>
struct StandardVertInput {
vec2 uv;
vec4 position;
vec3 normal;
vec4 tangent;
vec4 color;
};
in vec3 a_position;
#if CC_USE_ATTRIBUTE_UV0
in vec2 a_uv0;
#endif
#if CC_USE_ATTRIBUTE_COLOR
in vec4 a_color;
#endif
#if CC_USE_ATTRIBUTE_NORMAL
in vec3 a_normal;
#endif
#if CC_USE_ATTRIBUTE_TANGENT
in vec4 a_tangent;
#endif
void CCAttribute (out StandardVertInput In) {
In.position = vec4(a_position, 1.0);
#if CC_USE_ATTRIBUTE_UV0
In.uv = a_uv0;
#else
In.uv = vec2(0.0);
#endif
#if CC_USE_ATTRIBUTE_COLOR
In.color = a_color;
#else
In.color = vec4(1.0);
#endif
#if CC_USE_ATTRIBUTE_NORMAL
In.normal = a_normal;
#else
In.normal = vec3(0.0, 1.0, 0.0);
#endif
#if CC_USE_ATTRIBUTE_TANGENT
In.tangent = a_tangent;
#else
In.tangent = vec4(1.0, 0.0, 0.0, 0.0);
#endif
}
void CCVertInput(out StandardVertInput In) {
CCAttribute(In);
#if CC_USE_SKINNING
mat4 m = skinMatrix();
In.position = m * In.position;
#if CC_USE_ATTRIBUTE_NORMAL
In.normal = (m * vec4(In.normal, 0)).xyz;
#endif
#if CC_USE_ATTRIBUTE_TANGENT
In.tangent = m * In.tangent;
#endif
#endif
}

View File

@@ -0,0 +1,9 @@
// Copyright (c) 2017-2019 Xiamen Yaji Software Co., Ltd.
#include <gamma>
vec4 CCFragOutput (vec4 color) {
#if OUTPUT_TO_GAMMA
color.rgb = LinearToSRGB(color.rgb);
#endif
return color;
}

View File

@@ -0,0 +1,12 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
vec4 packDepthToRGBA(float depth) {
vec4 ret = vec4(1.0, 255.0, 65025.0, 160581375.0) * depth;
ret = fract(ret);
ret -= ret.yzww * vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);
return ret;
}
float unpackRGBAToDepth(vec4 color) {
return dot(color, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0));
}

View File

@@ -0,0 +1,175 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
mat3 transpose(mat3 v) {
mat3 tmp;
tmp[0] = vec3(v[0].x, v[1].x, v[2].x);
tmp[1] = vec3(v[0].y, v[1].y, v[2].y);
tmp[2] = vec3(v[0].z, v[1].z, v[2].z);
return tmp;
}
void ClipQuadToHorizon(inout vec3 L[5], out int n) {
// detect clipping config
int config = 0;
if (L[0].z > 0.0) config += 1;
if (L[1].z > 0.0) config += 2;
if (L[2].z > 0.0) config += 4;
if (L[3].z > 0.0) config += 8;
config = 15;
// clip
n = 0;
if (config == 0)
{
// clip all
}
else if (config == 1) // V1 clip V2 V3 V4
{
n = 3;
L[1] = -L[1].z * L[0] + L[0].z * L[1];
L[2] = -L[3].z * L[0] + L[0].z * L[3];
}
else if (config == 2) // V2 clip V1 V3 V4
{
n = 3;
L[0] = -L[0].z * L[1] + L[1].z * L[0];
L[2] = -L[2].z * L[1] + L[1].z * L[2];
}
else if (config == 3) // V1 V2 clip V3 V4
{
n = 4;
L[2] = -L[2].z * L[1] + L[1].z * L[2];
L[3] = -L[3].z * L[0] + L[0].z * L[3];
}
else if (config == 4) // V3 clip V1 V2 V4
{
n = 3;
L[0] = -L[3].z * L[2] + L[2].z * L[3];
L[1] = -L[1].z * L[2] + L[2].z * L[1];
}
else if (config == 5) // V1 V3 clip V2 V4) impossible
{
n = 0;
}
else if (config == 6) // V2 V3 clip V1 V4
{
n = 4;
L[0] = -L[0].z * L[1] + L[1].z * L[0];
L[3] = -L[3].z * L[2] + L[2].z * L[3];
}
else if (config == 7) // V1 V2 V3 clip V4
{
n = 5;
L[4] = -L[3].z * L[0] + L[0].z * L[3];
L[3] = -L[3].z * L[2] + L[2].z * L[3];
}
else if (config == 8) // V4 clip V1 V2 V3
{
n = 3;
L[0] = -L[0].z * L[3] + L[3].z * L[0];
L[1] = -L[2].z * L[3] + L[3].z * L[2];
L[2] = L[3];
}
else if (config == 9) // V1 V4 clip V2 V3
{
n = 4;
L[1] = -L[1].z * L[0] + L[0].z * L[1];
L[2] = -L[2].z * L[3] + L[3].z * L[2];
}
else if (config == 10) // V2 V4 clip V1 V3) impossible
{
n = 0;
}
else if (config == 11) // V1 V2 V4 clip V3
{
n = 5;
L[4] = L[3];
L[3] = -L[2].z * L[3] + L[3].z * L[2];
L[2] = -L[2].z * L[1] + L[1].z * L[2];
}
else if (config == 12) // V3 V4 clip V1 V2
{
n = 4;
L[1] = -L[1].z * L[2] + L[2].z * L[1];
L[0] = -L[0].z * L[3] + L[3].z * L[0];
}
else if (config == 13) // V1 V3 V4 clip V2
{
n = 5;
L[4] = L[3];
L[3] = L[2];
L[2] = -L[1].z * L[2] + L[2].z * L[1];
L[1] = -L[1].z * L[0] + L[0].z * L[1];
}
else if (config == 14) // V2 V3 V4 clip V1
{
n = 5;
L[4] = -L[0].z * L[3] + L[3].z * L[0];
L[0] = -L[0].z * L[1] + L[1].z * L[0];
}
else if (config == 15) // V1 V2 V3 V4
{
n = 4;
}
if (n == 3)
L[3] = L[0];
if (n == 4)
L[4] = L[0];
}
// https://eheitzresearch.wordpress.com/415-2/
float IntegrateEdge(vec3 v1, vec3 v2) {
float cosTheta = dot(v1, v2);
float theta = acos(cosTheta);
return cross(v1, v2).z * ((theta > 0.001) ? theta/sin(theta) : 4.0);
}
vec3 LTC_Evaluate(vec3 N, vec3 V, vec3 P, mat3 Minv, vec3 points[4]) {
// construct orthonormal basis around N
vec3 T1, T2;
T1 = normalize(V - N*dot(V, N));
T2 = cross(N, T1);
// rotate area light in (T1, T2, N) basis
Minv = Minv * transpose(mat3(T1, T2, N));
// polygon (allocate 5 vertices for clipping)
vec3 L[5];
L[0] = Minv * (points[0] - P);
L[1] = Minv * (points[1] - P);
L[2] = Minv * (points[2] - P);
L[3] = Minv * (points[3] - P);
int n;
ClipQuadToHorizon(L, n);
if (n == 0)
return vec3(0, 0, 0);
// project onto sphere
L[0] = normalize(L[0]);
L[1] = normalize(L[1]);
L[2] = normalize(L[2]);
L[3] = normalize(L[3]);
L[4] = normalize(L[4]);
// integrate
float sum = 0.0;
sum += IntegrateEdge(L[0], L[1]);
sum += IntegrateEdge(L[1], L[2]);
sum += IntegrateEdge(L[2], L[3]);
if (n >= 4)
sum += IntegrateEdge(L[3], L[4]);
if (n == 5)
sum += IntegrateEdge(L[4], L[0]);
sum = max(0.0, sum);
vec3 Lo_i = vec3(sum, sum, sum);
return Lo_i;
}

View File

@@ -0,0 +1,62 @@
uniform Constants{
vec4 mainTiling_Offset;
vec4 frameTile_velLenScale;
vec4 scale;
};
#include <cc-global>
#include <cc-local>
#include <transform>
out vec2 uv;
out vec4 color;
void computeVertPos(inout vec4 pos, vec2 vertOffset, vec4 q, vec3 s
#if CC_USE_BILLBOARD || CC_USE_VERTICAL_BILLBOARD
, mat4 viewInv
#endif
#if CC_USE_STRETCHED_BILLBOARD
, vec3 eye
, vec4 velocity
, float velocityScale
, float lengthScale
, float xIndex
#endif
) {
#if CC_USE_BILLBOARD
vec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);
vec3 camX = normalize(vec3(viewInv[0][0], viewInv[1][0], viewInv[2][0]));
vec3 camY = normalize(vec3(viewInv[0][1], viewInv[1][1], viewInv[2][1]));
vec3 camZ = normalize(vec3(viewInv[0][2], viewInv[1][2], viewInv[2][2]));
pos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, camZ, q);
#elif CC_USE_STRETCHED_BILLBOARD
vec3 camRight = normalize(cross(pos.xyz - eye, velocity.xyz)) * s.x;
vec3 camUp = velocity.xyz * velocityScale + normalize(velocity.xyz) * lengthScale * s.y;
pos.xyz += (camRight * abs(vertOffset.x) * sign(vertOffset.y)) - camUp * xIndex;
#elif CC_USE_HORIZONTAL_BILLBOARD
vec3 viewSpaceVert = vec3(vertOffset.x * s.x, vertOffset.y * s.y, 0.);
vec3 camX = vec3(1, 0, 0);
vec3 camY = vec3(0, 0, -1);
pos.xyz += rotateInLocalSpace(viewSpaceVert, camX, camY, cross(camX, camY), q);
#elif CC_USE_VERTICAL_BILLBOARD
vec2 viewSpaceVert = vec2(vertOffset.x * s.x, vertOffset.y * s.y);
rotateCorner(viewSpaceVert, q.z);
vec3 camX = normalize(vec3(cc_matView[0][0], cc_matView[1][0], cc_matView[2][0]));
vec3 camY = vec3(0, 1, 0);
vec3 offset = camX * viewSpaceVert.x + camY * viewSpaceVert.y;
pos.xyz += offset;
#else
pos.x += vertOffset.x;
pos.y += vertOffset.y;
#endif
}
vec2 computeUV(float frameIndex, vec2 vertIndex, vec2 frameTile){
vec2 aniUV = vec2(0, floor(frameIndex * frameTile.y));
aniUV.x = floor(frameIndex * frameTile.x * frameTile.y - aniUV.y * frameTile.x);
#if !CC_USE_MESH
vertIndex.y = 1. - vertIndex.y; // if using billboard ,y must be flipped.but mesh does not,why?
#endif
return (aniUV.xy + vertIndex) / vec2(frameTile.x, frameTile.y);
}

View File

@@ -0,0 +1,33 @@
precision mediump float;
#include <particle-common>
in vec3 a_position; // center position
in vec4 a_texCoord; // x:index y:size zw:texcoord
in vec3 a_texCoord1; // xyz:velocity
in vec3 a_texCoord2;
in vec4 a_color;
#if CC_DRAW_WIRE_FRAME
out vec3 vBarycentric;
#endif
vec4 vs_main() {
highp vec4 pos = vec4(a_position, 1);
vec4 velocity = vec4(a_texCoord1.xyz, 0);
#if !CC_USE_WORLD_SPACE
pos = cc_matWorld * pos;
velocity = cc_matWorld * velocity;
#endif
float vertOffset = (a_texCoord.x - 0.5) * a_texCoord.y;
vec3 camUp = normalize(cross(pos.xyz - cc_cameraPos.xyz, velocity.xyz));
pos.xyz += camUp * vertOffset;
pos = cc_matViewProj * pos;
uv = a_texCoord.zw * mainTiling_Offset.xy + mainTiling_Offset.zw;;
color = a_color;
#if CC_DRAW_WIRE_FRAME
vBarycentric = a_texCoord2;
#endif
return pos;
}

View File

@@ -0,0 +1,395 @@
precision mediump float;
#include <particle-common>
#define MAX_KEY_NUM 8
#define CURVE_MODE_CONSTANT 0
#define CURVE_MODE_RANDOM_CONSTANT 1
#define CURVE_MODE_CURVE 2
#define CURVE_MODE_RANDOM_CURVE 3
#define GRADIENT_MODE_FIX 0
#define GRADIENT_MODE_BLEND 1
#define GRADIENT_RANGE_MODE_COLOR 0
#define GRADIENT_RANGE_MODE_TWO_COLOR 1
#define GRADIENT_RANGE_MODE_RANDOM_COLOR 2
#define GRADIENT_RANGE_MODE_GRADIENT 3
#define GRADIENT_RANGE_MODE_TWO_GRADIENT 4
#define SIMULATE_SPACE_LOCAL 0
#define SIMULATE_SPACE_WORLD 1
#define ANIMATION_MODE_WHOLE_SHEET 0
#define ANIMATION_MODE_SINGLE_ROW 1
#define COLOR_OVERTIME_RAND_OFFSET 91041.
#define FORCE_OVERTIME_RAND_OFFSET 212165.
#define ROTATION_OVERTIME_RAND_OFFSET 125292.
#define SIZE_OVERTIME_RAND_OFFSET 39825.
#define TEXTURE_ANIMATION_RAND_OFFSET 90794.
#define VELOCITY_OVERTIME_RAND_OFFSET 197866.
#define DECL_CURVE_STRUCT(name) \
uniform CurveStruct_##name## { \
int u_##name##_curveMode; \
float u_##name##_minConstant; \
float u_##name##_maxConstant; \
float u_##name##_minKeyTime[MAX_KEY_NUM]; \
vec4 u_##name##_minKeyCoef[MAX_KEY_NUM]; \
vec4 u_##name##_maxKeyCoef[MAX_KEY_NUM]; \
float u_##name##_maxKeyTime[MAX_KEY_NUM]; \
};
#define DECL_CURVE_STRUCT_INT(name) \
uniform CurveStructInt_##name## { \
int u_##name##_curveMode; \
float u_##name##_minConstant; \
float u_##name##_maxConstant; \
float u_##name##_minKeyTime[MAX_KEY_NUM]; \
vec4 u_##name##_minKeyCoef[MAX_KEY_NUM]; \
vec4 u_##name##_maxKeyCoef[MAX_KEY_NUM]; \
float u_##name##_maxKeyTime[MAX_KEY_NUM]; \
float u_##name##_minIntegral[MAX_KEY_NUM - 1]; \
float u_##name##_maxIntegral[MAX_KEY_NUM - 1]; \
};
#define DECL_GRADIENT_STRUCT(name) \
uniform GradientStruct_##name## { \
int u_##name##_rangeMode; \
int u_##name##_minGradMode; \
int u_##name##_maxGradMode; \
vec4 u_##name##_minColor; \
vec4 u_##name##_maxColor; \
vec3 u_##name##_minColorKeyValue[MAX_KEY_NUM]; \
float u_##name##_minColorKeyTime[MAX_KEY_NUM]; \
float u_##name##_minAlphaKeyValue[MAX_KEY_NUM]; \
float u_##name##_minAlphaKeyTime[MAX_KEY_NUM]; \
vec3 u_##name##_maxColorKeyValue[MAX_KEY_NUM]; \
float u_##name##_maxColorKeyTime[MAX_KEY_NUM]; \
float u_##name##_maxAlphaKeyValue[MAX_KEY_NUM]; \
float u_##name##_maxAlphaKeyTime[MAX_KEY_NUM]; \
};
#define EVAL_CURVE_RANGE(name, t, rnd) \
evaluateCurveRange(u_##name##_curveMode, u_##name##_minConstant, u_##name##_maxConstant, u_##name##_minKeyTime, u_##name##_minKeyCoef, u_##name##_maxKeyTime, u_##name##_maxKeyCoef, t, rnd)
#define EVAL_CURVE_INTEGRAL(name, t, ts, rnd) \
evaluateCurveRangeIntegral(u_##name##_curveMode, u_##name##_minConstant, u_##name##_maxConstant, u_##name##_minKeyTime, u_##name##_minKeyCoef, u_##name##_minIntegral, u_##name##_maxKeyTime, u_##name##_maxKeyCoef, u_##name##_maxIntegral, t, ts, rnd)
#define EVAL_CURVE_INTEGRAL_TWICE(name, t, ts, rnd) \
evaluateCurveRangeIntegralTwice(u_##name##_curveMode, u_##name##_minConstant, u_##name##_maxConstant, u_##name##_minKeyTime, u_##name##_minKeyCoef, u_##name##_minIntegral, u_##name##_maxKeyTime, u_##name##_maxKeyCoef, u_##name##_maxIntegral, t, ts, rnd)
#define EVAL_GRADIENT_RANGE(name, t, rnd) \
evaluateGradientRange(u_##name##_rangeMode, u_##name##_minColor, u_##name##_maxColor, \
u_##name##_minGradMode, u_##name##_minColorKeyValue, u_##name##_minColorKeyTime, u_##name##_minAlphaKeyValue, u_##name##_minAlphaKeyTime, \
u_##name##_maxGradMode, u_##name##_maxColorKeyValue, u_##name##_maxColorKeyTime, u_##name##_maxAlphaKeyValue, u_##name##_maxAlphaKeyTime, t, rnd);
in vec4 a_position_starttime; // center position,particle start time
in vec4 a_vertIdx_size_angle; // xy:vertex index,z:size,w:angle
in vec4 a_color;
in vec4 a_dir_life; // xyz:particle start velocity,w:particle lifetime
in float a_rndSeed;
uniform Constants2 {
vec4 u_worldRot;
float u_psTime;
int u_velocity_space;
float u_speedModifier;
int u_force_space;
};
#if VELOCITY_OVERTIME_MODULE_ENABLE
// DECL_CURVE_STRUCT_INT(velocity_pos_x)
// DECL_CURVE_STRUCT_INT(velocity_pos_y)
// DECL_CURVE_STRUCT_INT(velocity_pos_z)
#if USE_STRETCHED_BILLBOARD
// DECL_CURVE_STRUCT(velocity_x)
// DECL_CURVE_STRUCT(velocity_y)
// DECL_CURVE_STRUCT(velocity_z)
#endif
#endif
#if FORCE_OVERTIME_MODULE_ENABLE
// DECL_CURVE_STRUCT_INT(force_pos_x)
// DECL_CURVE_STRUCT_INT(force_pos_y)
// DECL_CURVE_STRUCT_INT(force_pos_z)
#if USE_STRETCHED_BILLBOARD
// DECL_CURVE_STRUCT_INT(force_vel_x)
// DECL_CURVE_STRUCT_INT(force_vel_y)
// DECL_CURVE_STRUCT_INT(force_vel_z)
#endif
#endif
#if SIZE_OVERTIME_MODULE_ENABLE
// DECL_CURVE_STRUCT(size)
#endif
#if COLOR_OVERTIME_MODULE_ENABLE
// DECL_GRADIENT_STRUCT(color)
#endif
#if TEXTURE_ANIMATION_ENABLE
// DECL_CURVE_STRUCT(frameOverTime)
uniform Animation {
float u_cycles;
int u_animation_mode;
bool u_random_row;
int u_row_index;
};
#endif
#if ROTATE_OVERTIME_MODULE_ENABLE
// DECL_CURVE_STRUCT_INT(rotate)
#endif
float repeat(float t, float length) {
return t - floor(t / length) * length;
}
vec4 rotateQuat(vec4 p, vec4 q) {
vec3 iv = cross(q.xyz, p.xyz) + q.w * p.xyz;
vec3 res = p.xyz + 2.0 * cross(q.xyz, iv);
return vec4(res.xyz, p.w);
}
float random(float seed) {
seed = mod(seed, 233280.);
float q = (seed * 9301. + 49297.) / 233280.;
return fract(q);
}
float calcCurveValue(vec4 coef, float t) {
return t * (t * (t * coef.x + coef.y) + coef.z) + coef.w;
}
float evaluateCurve(float keyTime[MAX_KEY_NUM], vec4 keyCoef[MAX_KEY_NUM], float normalizedTime) {
for (int i = 0; i < MAX_KEY_NUM; i++) {
if (keyTime[i] > normalizedTime) {
return calcCurveValue(keyCoef[i], normalizedTime - (i == 0 ? 0. : keyTime[i - 1]));
}
}
}
float evaluateIntegral(float keyTime[MAX_KEY_NUM], vec4 keyCoef[MAX_KEY_NUM], float integral[MAX_KEY_NUM - 1], float normalizedTime, float ts) {
for (int i = 0; i < MAX_KEY_NUM; i++) {
if (keyTime[i] > normalizedTime) {
float t = normalizedTime - (i == 0 ? 0. : keyTime[i - 1]);
return ts * ((i - 1 < 0 ? 0. : integral[i - 1]) + t * calcCurveValue(keyCoef[i], t));
}
}
}
float evaluateIntegralTwice(float keyTime[MAX_KEY_NUM], vec4 keyCoef[MAX_KEY_NUM], float integral[MAX_KEY_NUM - 1], float normalizedTime, float ts) {
for (int i = 0; i < MAX_KEY_NUM; i++) {
if (keyTime[i] > normalizedTime) {
float t = normalizedTime - (i == 0 ? 0. : keyTime[i - 1]);
return ts * ts * ((i - 1 < 0 ? 0. : integral[i - 1]) + t * t * calcCurveValue(keyCoef[i], t));
}
}
}
float evaluateCurveRange(int mode, float minConstant, float maxConstant
, float minKeyTime[MAX_KEY_NUM], vec4 minKeyCoef[MAX_KEY_NUM]
, float maxKeyTime[MAX_KEY_NUM], vec4 maxKeyCoef[MAX_KEY_NUM]
, float t, float rnd) {
if (mode == CURVE_MODE_CONSTANT) {
return minConstant;
} else if (mode == CURVE_MODE_RANDOM_CONSTANT) {
return mix(minConstant, maxConstant, random(rnd));
} else if (mode == CURVE_MODE_CURVE) {
return evaluateCurve(minKeyTime, minKeyCoef, t);
} else if (mode == CURVE_MODE_RANDOM_CURVE) {
return mix(evaluateCurve(minKeyTime, minKeyCoef, t), evaluateCurve(maxKeyTime, maxKeyCoef, t), random(rnd));
}
}
float evaluateCurveRangeIntegral(int mode, float minConstant, float maxConstant
, float minKeyTime[MAX_KEY_NUM], vec4 minKeyCoef[MAX_KEY_NUM], float minIntegral[MAX_KEY_NUM - 1]
, float maxKeyTime[MAX_KEY_NUM], vec4 maxKeyCoef[MAX_KEY_NUM], float maxIntegral[MAX_KEY_NUM - 1]
, float t, float ts, float rnd) {
if (mode == CURVE_MODE_CONSTANT) {
return minConstant * t * ts;
} else if (mode == CURVE_MODE_RANDOM_CONSTANT) {
return mix(minConstant, maxConstant, random(rnd)) * t * ts;
} else if (mode == CURVE_MODE_CURVE) {
return evaluateIntegral(minKeyTime, minKeyCoef, minIntegral, t, ts);
} else if (mode == CURVE_MODE_RANDOM_CURVE) {
return mix(evaluateIntegral(minKeyTime, minKeyCoef, minIntegral, t, ts), evaluateIntegral(maxKeyTime, maxKeyCoef, maxIntegral, t, ts), random(rnd));
}
}
float evaluateCurveRangeIntegralTwice(int mode, float minConstant, float maxConstant
, float minKeyTime[MAX_KEY_NUM], vec4 minKeyCoef[MAX_KEY_NUM], float minIntegral[MAX_KEY_NUM - 1]
, float maxKeyTime[MAX_KEY_NUM], vec4 maxKeyCoef[MAX_KEY_NUM], float maxIntegral[MAX_KEY_NUM - 1]
, float t, float ts, float rnd) {
if (mode == CURVE_MODE_CONSTANT) {
return minConstant * t * t * ts * ts / 2.;
} else if (mode == CURVE_MODE_RANDOM_CONSTANT) {
return mix(minConstant, maxConstant, random(rnd)) * t * t * ts * ts / 2.;
} else if (mode == CURVE_MODE_CURVE) {
return evaluateIntegralTwice(minKeyTime, minKeyCoef, minIntegral, t, ts);
} else if (mode == CURVE_MODE_RANDOM_CURVE) {
return mix(evaluateIntegralTwice(minKeyTime, minKeyCoef, minIntegral, t, ts), evaluateIntegralTwice(maxKeyTime, maxKeyCoef, maxIntegral, t, ts), random(rnd));
}
}
vec4 evaluateGradient(int mode, float colorKeyTime[MAX_KEY_NUM], vec3 colorKeyValue[MAX_KEY_NUM]
, float alphaKeyTime[MAX_KEY_NUM], float alphaKeyValue[MAX_KEY_NUM]
, float t){
vec4 ret;
for (int i = 0; i < MAX_KEY_NUM; i++) {
if (t < colorKeyTime[i]) {
if (mode == GRADIENT_MODE_FIX) {
ret.xyz = colorKeyValue[i];
} else if (mode == GRADIENT_MODE_BLEND) {
ret.xyz = mix(colorKeyValue[i - 1], colorKeyValue[i], (t - colorKeyTime[i - 1]) / (colorKeyTime[i] - colorKeyTime[i - 1]));
}
break;
}
}
for (int i = 0; i < MAX_KEY_NUM; i++) {
if (t < alphaKeyTime[i]) {
if (mode == GRADIENT_MODE_FIX) {
ret.w = alphaKeyValue[i];
} else if (mode == GRADIENT_MODE_BLEND) {
ret.w = mix(alphaKeyValue[i - 1], alphaKeyValue[i], (t - alphaKeyTime[i - 1]) / (alphaKeyTime[i] - alphaKeyTime[i - 1]));
}
break;
}
}
return ret;
}
vec4 evaluateGradientRange(int rangeMode, vec4 minColor, vec4 maxColor,
int minGradMode, vec3 minColorKeyValue[MAX_KEY_NUM], float minColorKeyTime[MAX_KEY_NUM], float minAlphaKeyValue[MAX_KEY_NUM], float minAlphaKeyTime[MAX_KEY_NUM],
int maxGradMode, vec3 maxColorKeyValue[MAX_KEY_NUM], float maxColorKeyTime[MAX_KEY_NUM], float maxAlphaKeyValue[MAX_KEY_NUM], float maxAlphaKeyTime[MAX_KEY_NUM],
float t, float rnd){
if (rangeMode == GRADIENT_RANGE_MODE_COLOR) {
return minColor;
} else if (rangeMode == GRADIENT_RANGE_MODE_TWO_COLOR) {
return mix(minColor, maxColor, rnd);
} else if (rangeMode == GRADIENT_RANGE_MODE_GRADIENT) {
return evaluateGradient(minGradMode, minColorKeyTime, minColorKeyValue, minAlphaKeyTime, minAlphaKeyValue, t);
} else if (rangeMode == GRADIENT_RANGE_MODE_TWO_GRADIENT) {
return mix(evaluateGradient(minGradMode, minColorKeyTime, minColorKeyValue, minAlphaKeyTime, minAlphaKeyValue, t),
evaluateGradient(maxGradMode, maxColorKeyTime, maxColorKeyValue, maxAlphaKeyTime, maxAlphaKeyValue, t), rnd);
}
}
vec4 gpvs_main() {
vec4 pos = vec4(a_position_starttime.xyz, 1.);
float activeTime = u_psTime - a_position_starttime.w;
float normalizedTime = activeTime / a_dir_life.w;
#if VELOCITY_OVERTIME_MODULE_ENABLE
float speedModifier = u_speedModifier;
#else
float speedModifier = 1.;
#endif
pos.xyz += a_dir_life.xyz * activeTime * speedModifier;
#if USE_STRETCHED_BILLBOARD
vec4 velocity = vec4(a_dir_life.xyz, 0.);
velocity *= speedModifier;
#endif
#if !USE_WORLD_SPACE
pos = cc_matWorld * pos;
#if USE_STRETCHED_BILLBOARD
velocity = rotateQuat(velocity, u_worldRot);
#endif
#endif
#if VELOCITY_OVERTIME_MODULE_ENABLE
vec4 velocityTrack = vec4(EVAL_CURVE_INTEGRAL(velocity_pos_x, normalizedTime, a_dir_life.w, a_rndSeed + VELOCITY_OVERTIME_RAND_OFFSET), EVAL_CURVE_INTEGRAL(velocity_pos_y, normalizedTime, a_dir_life.w, a_rndSeed + VELOCITY_OVERTIME_RAND_OFFSET), EVAL_CURVE_INTEGRAL(velocity_pos_z, normalizedTime, a_dir_life.w, a_rndSeed + VELOCITY_OVERTIME_RAND_OFFSET), 0);
velocityTrack = velocityTrack * speedModifier;
if (u_velocity_space == SIMULATE_SPACE_LOCAL) {
velocityTrack = rotateQuat(velocityTrack, u_worldRot);
}
pos += velocityTrack;
#if USE_STRETCHED_BILLBOARD
vec4 velocityVel = vec4(EVAL_CURVE_RANGE(velocity_x, normalizedTime, a_dir_life.w, a_rndSeed + VELOCITY_OVERTIME_RAND_OFFSET), EVAL_CURVE_RANGE(velocity_y, normalizedTime, a_dir_life.w, a_rndSeed + VELOCITY_OVERTIME_RAND_OFFSET), EVAL_CURVE_RANGE(velocity_z, normalizedTime, a_dir_life.w, a_rndSeed + VELOCITY_OVERTIME_RAND_OFFSET), 0);
if (u_velocity_space == SIMULATE_SPACE_LOCAL) {
velocityVel = rotateQuat(velocityVel, u_worldRot);
}
velocityVel *= speedModifier;
velocity += velocityVel;
#endif
#endif
#if FORCE_OVERTIME_MODULE_ENABLE
vec4 forceTrack = vec4(EVAL_CURVE_INTEGRAL_TWICE(force_pos_x, normalizedTime, a_dir_life.w, a_rndSeed + FORCE_OVERTIME_RAND_OFFSET), EVAL_CURVE_INTEGRAL_TWICE(force_pos_y, normalizedTime, a_dir_life.w, a_rndSeed + FORCE_OVERTIME_RAND_OFFSET), EVAL_CURVE_INTEGRAL_TWICE(force_pos_z, normalizedTime, a_dir_life.w, a_rndSeed + FORCE_OVERTIME_RAND_OFFSET), 0);
forceTrack = forceTrack * speedModifier;
if (u_force_space == SIMULATE_SPACE_LOCAL) {
forceTrack = rotateQuat(forceTrack, u_worldRot);
}
pos += forceTrack;
#if USE_STRETCHED_BILLBOARD
vec4 forceVel = vec4(EVAL_CURVE_INTEGRAL(force_vel_x, normalizedTime, a_dir_life.w, a_rndSeed + FORCE_OVERTIME_RAND_OFFSET), EVAL_CURVE_INTEGRAL(force_vel_y, normalizedTime, a_dir_life.w, a_rndSeed + FORCE_OVERTIME_RAND_OFFSET), EVAL_CURVE_INTEGRAL(force_vel_z, normalizedTime, a_dir_life.w, a_rndSeed + FORCE_OVERTIME_RAND_OFFSET), 0);
if (u_force_space == SIMULATE_SPACE_LOCAL) {
forceVel = rotateQuat(forceVel, u_worldRot);
}
forceVel *= speedModifier;
velocity += forceVel;
#endif
#endif
float size = a_vertIdx_size_angle.z;
#if SIZE_OVERTIME_MODULE_ENABLE
float sizeModifier = EVAL_CURVE_RANGE(size, normalizedTime, a_rndSeed + SIZE_OVERTIME_RAND_OFFSET);
size *= sizeModifier;
#endif
vec2 cornerOffset = vec2((a_vertIdx_size_angle.xy - 0.5) * size);
#if !USE_STRETCHED_BILLBOARD
float angle = a_vertIdx_size_angle.w;
#if ROTATE_OVERTIME_MODULE_ENABLE
angle += EVAL_CURVE_INTEGRAL(rotate, normalizedTime, a_dir_life.w, a_rndSeed + ROTATION_OVERTIME_RAND_OFFSET);
#endif
rotateCorner(cornerOffset, angle);
#endif
computeVertPos(pos, cornerOffset
#if USE_BILLBOARD || USE_VERTICAL_BILLBOARD
, cc_matView
#endif
#if USE_STRETCHED_BILLBOARD
, cc_cameraPos
, velocity
, velocityScale
, lengthScale
, size
, a_vertIdx_size_angle.x
#endif
);
pos = cc_matViewProj * pos;
float frameIndex = 0.;
#if TEXTURE_ANIMATION_ENABLE
if (u_animation_mode == ANIMATION_MODE_WHOLE_SHEET) {
frameIndex = repeat(u_cycles * EVAL_CURVE_RANGE(frameOverTime, normalizedTime, a_rndSeed + TEXTURE_ANIMATION_RAND_OFFSET), 1.);
} else if (u_animation_mode == ANIMATION_MODE_SINGLE_ROW) {
float rowLength = 1. / frameTile_velLenScale.y;
if (u_random_row) {
float f = repeat(u_cycles * EVAL_CURVE_RANGE(frameOverTime, normalizedTime, a_rndSeed + TEXTURE_ANIMATION_RAND_OFFSET), 1.);
float startRow = floor(random(floor(u_psTime * 1000.)) * frameTile_velLenScale.y);
float from = startRow * rowLength;
float to = from + rowLength;
frameIndex = mix(from, to, f);
}
else {
float from = float(u_row_index) * rowLength;
float to = from + rowLength;
frameIndex = mix(from, to, repeat(u_cycles * EVAL_CURVE_RANGE(frameOverTime, normalizedTime, a_rndSeed + TEXTURE_ANIMATION_RAND_OFFSET), 1.));
}
}
#endif
uv = computeUV(frameIndex, a_vertIdx_size_angle.xy, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainOffset.zw;
#if COLOR_OVERTIME_MODULE_ENABLE
color = a_color * EVAL_GRADIENT_RANGE(color, normalizedTime, a_rndSeed + COLOR_OVERTIME_RAND_OFFSET);
#else
color = a_color;
#endif
return pos;
}

View File

@@ -0,0 +1,75 @@
precision highp float;
#include <transform>
#include <particle-common>
#include <cc-local>
in vec3 a_position; // center position
in vec3 a_texCoord; // xy:vertex index,z:frame index
in vec3 a_texCoord1; // size
in vec3 a_texCoord2; // rotation
in vec4 a_color;
#if CC_USE_STRETCHED_BILLBOARD
in vec3 a_color1; // velocity.x, velocity.y, velocity.z, scale
#endif
#if CC_USE_MESH
in vec3 a_texCoord3; // mesh vertices
in vec3 a_normal; // mesh normal
in vec4 a_color1; // mesh color
#endif
vec4 lpvs_main() {
vec3 compScale = scale.xyz * a_texCoord1;
vec4 pos = vec4(a_position, 1);
#if CC_USE_STRETCHED_BILLBOARD
vec4 velocity = vec4(a_color1.xyz, 0);
#endif
#if !CC_USE_WORLD_SPACE
// simulate in world space. apply cc_matWorld matrix on CPU side.
pos = cc_matWorld * pos;
#if CC_USE_STRETCHED_BILLBOARD
velocity = cc_matWorld * velocity;
#endif
#endif
#if !CC_USE_MESH
vec2 cornerOffset = vec2((a_texCoord.xy - 0.5));
#if CC_USE_BILLBOARD
vec3 rotEuler = a_texCoord2;
#elif CC_USE_STRETCHED_BILLBOARD
vec3 rotEuler = vec3(0.);
#else
vec3 rotEuler = vec3(0., 0., a_texCoord2.z);
#endif
computeVertPos(pos, cornerOffset, quaternionFromEuler(rotEuler), compScale
#if CC_USE_BILLBOARD || CC_USE_VERTICAL_BILLBOARD
, cc_matViewInv
#endif
#if CC_USE_STRETCHED_BILLBOARD
, cc_cameraPos.xyz
, velocity
, frameTile_velLenScale.z
, frameTile_velLenScale.w
, a_texCoord.x
#endif
);
color = a_color;
#else
mat4 xformNoScale = matrixFromRT(quaternionFromEuler(a_texCoord2), pos.xyz);
mat4 xform = matFromRTS(quaternionFromEuler(a_texCoord2), pos.xyz, compScale);
pos = xform * vec4(a_texCoord3, 1);
vec4 normal = xformNoScale * vec4(a_normal, 0);
color = a_color * a_color1;
#endif
uv = computeUV(a_texCoord.z, a_texCoord.xy, frameTile_velLenScale.xy) * mainTiling_Offset.xy + mainTiling_Offset.zw;
pos = cc_matViewProj * pos;
return pos;
}

View File

@@ -0,0 +1,102 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
precision highp float;
#include <cc-global>
#include <texture>
#include <output>
#include <alpha-test>
uniform PhongFrag {
lowp vec4 diffuseColor;
lowp vec4 specularColor;
lowp vec4 emissiveColor;
float glossiness;
};
#if USE_DIFFUSE_TEXTURE
uniform sampler2D diffuseTexture;
#endif
#if USE_SPECULAR && USE_SPECULAR_TEXTURE
uniform sampler2D specularTexture;
#endif
#if USE_EMISSIVE && USE_EMISSIVE_TEXTURE
uniform sampler2D emissiveTexture;
#endif
#if USE_NORMAL_TEXTURE
in vec3 v_tangent;
in vec3 v_bitangent;
uniform sampler2D normalTexture;
#endif
#define CC_USE_TEXTURE CC_USE_ATTRIBUTE_UV0 && (USE_DIFFUSE_TEXTURE || (USE_EMISSIVE && USE_EMISSIVE_TEXTURE) || (USE_SPECULAR && USE_SPECULAR_TEXTURE) || USE_NORMAL_TEXTURE)
in vec3 v_worldNormal;
in vec3 v_worldPos;
in vec3 v_viewDirection;
#if CC_USE_TEXTURE
in mediump vec2 v_uv0;
#endif
#if CC_USE_ATTRIBUTE_COLOR
in lowp vec4 v_color;
#endif
#include <shading-phong>
void surf (out PhongSurface s) {
vec4 diffuse = vec4(1, 1, 1, 1);
#if CC_USE_ATTRIBUTE_COLOR
diffuse *= v_color;
#endif
diffuse *= diffuseColor;
#if USE_DIFFUSE_TEXTURE
CCTexture(diffuseTexture, v_uv0, diffuse);
#endif
ALPHA_TEST(diffuse);
s.diffuse = diffuse.rgb;
s.opacity = diffuse.a;
#if USE_EMISSIVE
s.emissive = emissiveColor.rgb;
#if USE_EMISSIVE_TEXTURE
CCTextureRGB(emissiveTexture, v_uv0, s.emissive);
#endif
#endif
#if USE_SPECULAR
s.specular = specularColor.rgb;
#if USE_SPECULAR_TEXTURE
CCTextureRGB(specularTexture, v_uv0, s.specular);
#endif
#endif
s.normal = v_worldNormal;
#if USE_NORMAL_TEXTURE
vec3 nmmp = texture(normalTexture, v_uv0).xyz - vec3(0.5);
s.normal =
nmmp.x * normalize(v_tangent) +
nmmp.y * normalize(v_bitangent) +
nmmp.z * normalize(s.normal);
s.normal = normalize(s.normal);
#endif
s.position = v_worldPos;
s.viewDirection = v_viewDirection;
s.glossiness = glossiness;
}
void main () {
PhongSurface s;
surf(s);
vec4 color = CCPhongShading(s);
gl_FragColor = CCFragOutput(color);
}

View File

@@ -0,0 +1,60 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
precision highp float;
#include <cc-local>
#include <cc-global>
#include <input-standard>
#include <shadow>
#define CC_USE_TEXTURE CC_USE_ATTRIBUTE_UV0 && (USE_DIFFUSE_TEXTURE || USE_EMISSIVE_TEXTURE || USE_SPECULAR_TEXTURE || USE_NORMAL_TEXTURE)
uniform MAIN_TILING {
vec2 mainTiling;
vec2 mainOffset;
};
#if CC_USE_TEXTURE
out mediump vec2 v_uv0;
#endif
#if CC_USE_ATTRIBUTE_COLOR
out lowp vec4 v_color;
#endif
#if USE_NORMAL_TEXTURE
out vec3 v_tangent;
out vec3 v_bitangent;
#endif
out vec3 v_worldNormal;
out vec3 v_worldPos;
out vec3 v_viewDirection;
void main () {
StandardVertInput In;
CCVertInput(In);
vec4 position = In.position;
v_worldNormal = normalize((cc_matWorldIT * vec4(In.normal, 0)).xyz);
v_worldPos = (cc_matWorld * position).xyz;
v_viewDirection = normalize(cc_cameraPos.xyz - v_worldPos);
#if CC_USE_TEXTURE
v_uv0 = In.uv * mainTiling + mainOffset;
#endif
#if CC_USE_ATTRIBUTE_COLOR
v_color = In.color;
#endif
#if USE_NORMAL_TEXTURE
v_tangent = normalize((cc_matWorld * vec4(In.tangent.xyz, 0.0)).xyz);
v_bitangent = cross(v_worldNormal, v_tangent) * In.tangent.w; // note the cross order
#endif
CCShadowInput(v_worldPos);
gl_Position = cc_matViewProj * cc_matWorld * position;
}

View File

@@ -0,0 +1,11 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
precision highp float;
in float v_depth;
#include <packing>
void main () {
gl_FragColor = packDepthToRGBA(v_depth);
}

View File

@@ -0,0 +1,29 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
precision highp float;
in vec3 a_position;
#include <cc-local>
#pragma builtin(global)
uniform CC_SHADOW_MAP {
mat4 cc_shadow_map_lightViewProjMatrix;
vec4 cc_shadow_map_info; // [minDepth, maxDepth, depthScale, darkness]
float cc_shadow_map_bias;
};
out float v_depth;
#include <skinning>
void main () {
vec4 position = vec4(a_position, 1);
SKIN_VERTEX(position);
gl_Position = cc_shadow_map_lightViewProjMatrix * cc_matWorld * position;
// compute v_depth according to active camera's minDepth and maxDepth.
v_depth = ((gl_Position.z + cc_shadow_map_info.x) / (cc_shadow_map_info.x + cc_shadow_map_info.y)) + cc_shadow_map_bias;
}

View File

@@ -0,0 +1,41 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
precision highp float;
#include <alpha-test>
#include <texture>
#include <output>
uniform UNLIT {
lowp vec4 diffuseColor;
};
#if USE_DIFFUSE_TEXTURE
uniform sampler2D diffuseTexture;
#endif
#define CC_USE_TEXTURE CC_USE_ATTRIBUTE_UV0 && USE_DIFFUSE_TEXTURE
#if CC_USE_ATTRIBUTE_COLOR
in lowp vec4 v_color;
#endif
#if CC_USE_TEXTURE
in mediump vec2 v_uv0;
#endif
void main () {
vec4 color = diffuseColor;
#if CC_USE_TEXTURE
CCTexture(diffuseTexture, v_uv0, color);
#endif
#if CC_USE_ATTRIBUTE_COLOR
color *= v_color;
#endif
ALPHA_TEST(color);
gl_FragColor = CCFragOutput(color);
}

View File

@@ -0,0 +1,38 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
precision highp float;
#include <cc-local>
#include <cc-global>
#include <skinning>
#include <input-standard>
#define CC_USE_TEXTURE CC_USE_ATTRIBUTE_UV0 && USE_DIFFUSE_TEXTURE
uniform MAIN_TILING {
vec2 mainTiling;
vec2 mainOffset;
};
#if CC_USE_TEXTURE
out mediump vec2 v_uv0;
#endif
#if CC_USE_ATTRIBUTE_COLOR
out lowp vec4 v_color;
#endif
void main () {
StandardVertInput In;
CCVertInput(In);
#if CC_USE_ATTRIBUTE_COLOR
v_color = In.color;
#endif
#if CC_USE_TEXTURE
v_uv0 = In.uv * mainTiling + mainOffset;
#endif
gl_Position = cc_matViewProj * cc_matWorld * In.position;
}

View File

@@ -0,0 +1,59 @@
#include <cc-lights>
struct PhongSurface {
vec3 diffuse;
vec3 emissive;
vec3 specular;
float opacity;
float glossiness;
vec3 position;
vec3 normal;
vec3 viewDirection;
};
Lighting brdf (PhongSurface s, LightInfo info) {
Lighting result;
float ndh = 0.0;
// Get the half direction in world space
vec3 halfDir = normalize(s.viewDirection + info.lightDir);
float NdotH = max(0.0, dot(s.normal, halfDir));
NdotH = pow(NdotH, max(1.0, s.glossiness * 128.0));
result.diffuse = info.radiance * max(0.0, dot(s.normal, info.lightDir));
result.specular = info.radiance * NdotH;
return result;
}
vec4 composePhongShading (Lighting lighting, PhongSurface s) {
vec4 o = vec4(0.0, 0.0, 0.0, 1.0);
//diffuse is always calculated
o.rgb = lighting.diffuse * s.diffuse;
#if USE_EMISSIVE
o.rgb += s.emissive;
#endif
#if USE_SPECULAR
o.rgb += lighting.specular * s.specular;
#endif
o.a = s.opacity;
return o;
}
vec3 ambient(PhongSurface s, vec4 ambientColor) {
return s.diffuse * ambientColor.rgb;
}
vec4 CCPhongShading (in PhongSurface s) {
Lighting result;
CC_CALC_LIGHTS(s, result, brdf, ambient)
return composePhongShading(result, s);
}

View File

@@ -0,0 +1,72 @@
// Copyright (c) 2017-2019 Xiamen Yaji Software Co., Ltd.
#include <cc-global>
#include <cc-lights>
struct ToonSurface {
vec4 baseColor;
// specular
vec3 specular;
float specularThreshold;
// these need to be in the same coordinate system
vec3 position;
vec3 normal;
vec3 viewDirection;
// emissive
vec3 emissive;
// shadow
vec3 shadowColor;
float shadowIntensity;
vec3 highlightColor;
// light
float lightThreshold;
float lightSmoothness;
};
const float T_H = 0.25;
float TreshHoldLighting(float lThreshold, float smoothness, float v) {
return smoothstep(lThreshold-smoothness*T_H, lThreshold+smoothness*T_H, v);
}
Lighting toon (ToonSurface s, LightInfo info) {
Lighting result;
vec3 N = s.normal;
vec3 L = info.lightDir;
vec3 V = s.viewDirection;
vec3 H = normalize(L + V);
float NL = 0.5 * dot(N, L) + 0.5;
float NH = 0.5 * dot(H, N) + 0.5;
vec3 c = vec3(0.0);
vec3 attenuation = info.radiance;
vec3 lightColor = info.lightColor.rgb;
// diffuse
vec3 shadowColor = mix(s.highlightColor * lightColor, s.shadowColor, s.shadowIntensity);
vec3 diffuse = TreshHoldLighting(s.lightThreshold, s.lightSmoothness, NL) * attenuation;
diffuse = mix(shadowColor, s.highlightColor * lightColor, diffuse);
result.diffuse = diffuse * s.baseColor.rgb;
// specular
float specularWeight = 1.0 - pow(s.specularThreshold, 5.0);
float specularMask = step(specularWeight, NH);
vec3 specular = s.specular.rgb * specularMask;
result.specular = specular * attenuation;
return result;
}
vec3 ambient(ToonSurface s, vec4 ambientColor) {
return s.baseColor.rgb * ambientColor.rgb;
}
vec4 CCToonShading (ToonSurface s) {
Lighting result;
CC_CALC_LIGHTS(s, result, toon, ambient)
vec3 finalColor = result.diffuse + result.specular + s.emissive;
return vec4(finalColor, s.baseColor.a);
}

View File

@@ -0,0 +1,100 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
#define CC_MAX_SHADOW_LIGHTS 2
#define CC_SHADOW_TYPE_HARD 2
#define CC_SHADOW_TYPE_SOFT_PCF3X3 3
#define CC_SHADOW_TYPE_SOFT_PCF5X5 4
#define CC_DEFINE_SHADOW_MAP(index) \
#if CC_NUM_SHADOW_LIGHTS > index \
#pragma builtin(global) \
uniform sampler2D cc_shadow_map_##index; \
#endif
#if CC_USE_SHADOW_MAP && CC_NUM_SHADOW_LIGHTS > 0
#pragma builtin(global)
uniform CC_SHADOW {
mat4 cc_shadow_lightViewProjMatrix[CC_MAX_SHADOW_LIGHTS];
vec4 cc_shadow_info[CC_MAX_SHADOW_LIGHTS]; // [minDepth, maxDepth, shadow resolution, darkness]
};
CC_DEFINE_SHADOW_MAP(0)
CC_DEFINE_SHADOW_MAP(1)
varying vec4 v_posLightSpace[CC_MAX_SHADOW_LIGHTS];
varying float v_depth[CC_MAX_SHADOW_LIGHTS];
#endif
void CCShadowInput (vec3 worldPos) {
#if CC_USE_SHADOW_MAP && CC_NUM_SHADOW_LIGHTS > 0
for (int i = 0; i < CC_NUM_SHADOW_LIGHTS; i++) {
v_posLightSpace[i] = cc_shadow_lightViewProjMatrix[i] * vec4(worldPos, 1.0);
v_depth[i] = (v_posLightSpace[i].z + cc_shadow_info[i].x) / (cc_shadow_info[i].x + cc_shadow_info[i].y);
}
#endif
}
#include <packing>
float getDepth(sampler2D shadowMap, vec2 shadowUV) {
return unpackRGBAToDepth(texture(shadowMap, shadowUV));
}
float computeFallOff(float shadow, vec2 coords, float frustumEdgeFalloff) {
// float mask = smoothstep(1.0 - frustumEdgeFalloff, 1.0, clamp(dot(coords, coords), 0.0, 1.0));
// return mix(esm, 1.0, mask);
return shadow;
}
// standard hard shadow
float shadowSimple(sampler2D shadowMap, vec2 shadowUV, float currentDepth, float darkness) {
float closestDepth = getDepth(shadowMap, shadowUV);
return currentDepth > closestDepth ? 1.0 - darkness : 1.0;
}
// PCF
float shadowPCF3X3(sampler2D shadowMap, vec2 shadowUV, float currentDepth, float darkness, float shadowSize) {
float shadow = 0.0;
for (int x = -1; x <= 1; ++x) {
for (int y = -1; y <= 1; ++y) {
float closestDepth = getDepth(shadowMap, shadowUV + vec2(x, y) * 1.0/shadowSize);
shadow += currentDepth > closestDepth ? 1.0 - darkness : 1.0;
}
}
shadow /= 9.0;
return shadow;
}
float shadowPCF5X5(sampler2D shadowMap, vec2 shadowUV, float currentDepth, float darkness, float shadowSize) {
float shadow = 0.0;
for (int x = -2; x <= 2; ++x) {
for (int y = -2; y <= 2; ++y) {
float closestDepth = getDepth(shadowMap, shadowUV + vec2(x, y) * 1.0/shadowSize);
shadow += currentDepth > closestDepth ? 1.0 - darkness : 1.0;
}
}
shadow /= 25.0;
return shadow;
}
#define CC_CALC_SHADOW(index, light) \
#if CC_USE_SHADOW_MAP && CC_NUM_SHADOW_LIGHTS > index \
float shadow_##index = 1.0; \
vec2 projCoords##index = v_posLightSpace[index].xy / v_posLightSpace[index].w; \
vec2 shadowUV##index = projCoords##index * 0.5 + vec2(0.5); /*(-1, 1) => (0, 1)*/ \
if (shadowUV##index.x >= 0.0 && shadowUV##index.x <= 1.0 && shadowUV##index.y >= 0.0 && shadowUV##index.y <= 1.0) { \
float currentDepth##index = clamp(v_depth[index], 0.0, 1.0); \
#if CC_SHADOW_##index##_TYPE == CC_SHADOW_TYPE_SOFT_PCF3X3 \
shadow_##index = shadowPCF3X3(cc_shadow_map_##index, shadowUV##index, currentDepth##index, cc_shadow_info[index].w, cc_shadow_info[index].z); \
#elif CC_SHADOW_##index##_TYPE == CC_SHADOW_TYPE_SOFT_PCF5X5 \
shadow_##index = shadowPCF5X5(cc_shadow_map_##index, shadowUV##index, currentDepth##index, cc_shadow_info[index].w, cc_shadow_info[index].z); \
#else \
shadow_##index = shadowSimple(cc_shadow_map_##index, shadowUV##index, currentDepth##index, cc_shadow_info[index].w); \
#endif \
shadow_##index = computeFallOff(shadow_##index, projCoords##index, 0.0); \
} \
\
light.diffuse *= shadow_##index; \
light.specular *= shadow_##index; \
#endif

View File

@@ -0,0 +1,127 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
#if CC_USE_SKINNING
in vec4 a_weights;
in vec4 a_joints;
#if CC_USE_JOINTS_TEXTRUE
uniform SKINNING {
vec2 jointsTextureSize;
};
#pragma builtin(local)
uniform sampler2D jointsTexture;
#if CC_JOINTS_TEXTURE_FLOAT32
mat4 getBoneMatrix(const in float i) {
float width = jointsTextureSize.x;
float height = jointsTextureSize.y;
float j = i * 4.0;
float x = mod(j, width);
float y = floor(j / width);
float dx = 1.0 / width;
float dy = 1.0 / height;
y = dy * (y + 0.5);
vec4 v1 = texture(jointsTexture, vec2(dx * (x + 0.5), y));
vec4 v2 = texture(jointsTexture, vec2(dx * (x + 1.5), y));
vec4 v3 = texture(jointsTexture, vec2(dx * (x + 2.5), y));
vec4 v4 = texture(jointsTexture, vec2(dx * (x + 3.5), y));
return mat4(v1, v2, v3, v4);
}
#else
float decode32(vec4 rgba) {
float Sign = 1.0 - step(128.0, rgba[0]) * 2.0;
float Exponent = 2.0 * mod(rgba[0], 128.0) + step(128.0, rgba[1]) - 127.0;
float Mantissa = mod(rgba[1], 128.0) * 65536.0 + rgba[2] * 256.0 + rgba[3] + 8388608.0;
return Sign * exp2(Exponent - 23.0) * Mantissa;
}
vec4 decodevec4 (vec4 x, vec4 y, vec4 z, vec4 w) {
// TODO: check this on big endian devices
return vec4(
decode32(x.wzyx * 255.0),
decode32(y.wzyx * 255.0),
decode32(z.wzyx * 255.0),
decode32(w.wzyx * 255.0)
);
}
vec4 decodevec4 (float dx, float x, float y) {
return decodevec4(
texture(jointsTexture, vec2(dx * (x + 0.5), y)),
texture(jointsTexture, vec2(dx * (x + 1.5), y)),
texture(jointsTexture, vec2(dx * (x + 2.5), y)),
texture(jointsTexture, vec2(dx * (x + 3.5), y))
);
}
mat4 getBoneMatrix(const in float i) {
float width = jointsTextureSize.x;
float height = jointsTextureSize.y;
float j = i * 16.0;
float x = mod(j, width);
float y = floor(j / width);
float dx = 1.0 / width;
float dy = 1.0 / height;
y = dy * (y + 0.5);
vec4 v1 = decodevec4(dx, x, y);
vec4 v2 = decodevec4(dx, x+4.0, y);
vec4 v3 = decodevec4(dx, x+8.0, y);
vec4 v4 = decodevec4(dx, x+12.0, y);
return mat4(v1, v2, v3, v4);
}
#endif
#else
#define CC_JOINT_MATRICES_SIZE 50
#pragma builtin(local)
uniform JOINT_MATRIX {
mat4 jointMatrices[CC_JOINT_MATRICES_SIZE];
};
mat4 getBoneMatrix(const in float i) {
return jointMatrices[int(i)];
}
#endif
mat4 skinMatrix() {
return
getBoneMatrix(a_joints.x) * a_weights.x +
getBoneMatrix(a_joints.y) * a_weights.y +
getBoneMatrix(a_joints.z) * a_weights.z +
getBoneMatrix(a_joints.w) * a_weights.w
;
}
#endif
void SKIN_VERTEX(inout vec4 a1) {
#if CC_USE_SKINNING
mat4 m = skinMatrix();
a1 = m * a1;
#endif
}
void SKIN_VERTEX(inout vec4 a1, inout vec4 a2) {
#if CC_USE_SKINNING
mat4 m = skinMatrix();
a1 = m * a1;
a2 = m * a2;
#endif
}
void SKIN_VERTEX(inout vec4 a1, inout vec4 a2, inout vec4 a3) {
#if CC_USE_SKINNING
mat4 m = skinMatrix();
a1 = m * a1;
a2 = m * a2;
a3 = m * a3;
#endif
}

View File

@@ -0,0 +1,27 @@
#include <gamma>
#define CCTexture(_texture_, _uv_, _color_) \
vec4 _texture_##_tmp = texture(_texture_, _uv_); \
#if CC_USE_ALPHA_ATLAS_##_texture_ \
_texture_##_tmp.a *= texture(_texture_, _uv_ + vec2(0, 0.5)).r; \
#endif \
#if INPUT_IS_GAMMA \
_color_.rgb *= SRGBToLinear(_texture_##_tmp.rgb); \
_color_.a *= _texture_##_tmp.a; \
#else \
_color_ *= _texture_##_tmp; \
#endif \
#pragma // empty pragma trick to get rid of trailing semicolons at effect compile time
#define CCTextureRGB(_texture_, _uv_, _color_) \
vec4 _texture_##_tmp = texture(_texture_, _uv_); \
#if CC_USE_ALPHA_ATLAS_##_texture_ \
_texture_##_tmp.a *= texture(_texture_, _uv_ + vec2(0, 0.5)).r; \
#endif \
#if INPUT_IS_GAMMA \
_color_.rgb *= SRGBToLinear(_texture_##_tmp.rgb); \
#else \
_color_.rgb *= _texture_##_tmp.rgb; \
#endif \
#pragma // empty pragma trick to get rid of trailing semicolons at effect compile time

View File

@@ -0,0 +1,170 @@
vec4 quaternionFromAxisAngle(float angle, vec3 axis){
angle /= 2.;
float s = sin(angle);
vec4 res;
res.xyz = s * axis;
res.w = cos(angle);
return res;
}
vec4 quaternionFromAxis(vec3 xAxis,vec3 yAxis,vec3 zAxis){
mat3 m = mat3(xAxis,yAxis,zAxis);
float trace = m[0][0] + m[1][1] + m[2][2];
vec4 quat;
if (trace > 0.) {
float s = 0.5 / sqrt(trace + 1.0);
quat.w = 0.25 / s;
quat.x = (m[2][1] - m[1][2]) * s;
quat.y = (m[0][2] - m[2][0]) * s;
quat.z = (m[1][0] - m[0][1]) * s;
} else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) {
float s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);
quat.w = (m[2][1] - m[1][2]) / s;
quat.x = 0.25 * s;
quat.y = (m[0][1] + m[1][0]) / s;
quat.z = (m[0][2] + m[2][0]) / s;
} else if (m[1][1] > m[2][2]) {
float s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);
quat.w = (m[0][2] - m[2][0]) / s;
quat.x = (m[0][1] + m[1][0]) / s;
quat.y = 0.25 * s;
quat.z = (m[1][2] + m[2][1]) / s;
} else {
float s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);
quat.w = (m[1][0] - m[0][1]) / s;
quat.x = (m[0][2] + m[2][0]) / s;
quat.y = (m[1][2] + m[2][1]) / s;
quat.z = 0.25 * s;
}
float len = quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w;
if (len > 0.) {
len = 1. / sqrt(len);
quat.x = quat.x * len;
quat.y = quat.y * len;
quat.z = quat.z * len;
quat.w = quat.w * len;
}
return quat;
}
vec4 quaternionFromEuler(vec3 angle){
float x = angle.x / 2.;
float y = angle.y / 2.;
float z = angle.z / 2.;
float sx = sin(x);
float cx = cos(x);
float sy = sin(y);
float cy = cos(y);
float sz = sin(z);
float cz = cos(z);
vec4 quat = vec4(0);
quat.x = sx * cy * cz + cx * sy * sz;
quat.y = cx * sy * cz + sx * cy * sz;
quat.z = cx * cy * sz - sx * sy * cz;
quat.w = cx * cy * cz - sx * sy * sz;
return quat;
}
mat4 matrixFromRT(vec4 q, vec3 p){
float x2 = q.x + q.x;
float y2 = q.y + q.y;
float z2 = q.z + q.z;
float xx = q.x * x2;
float xy = q.x * y2;
float xz = q.x * z2;
float yy = q.y * y2;
float yz = q.y * z2;
float zz = q.z * z2;
float wx = q.w * x2;
float wy = q.w * y2;
float wz = q.w * z2;
return mat4(
1. - (yy + zz), xy + wz, xz - wy, 0,
xy - wz, 1. - (xx + zz), yz + wx, 0,
xz + wy, yz - wx, 1. - (xx + yy), 0,
p.x, p.y, p.z, 1
);
}
mat4 matFromRTS(vec4 q, vec3 t, vec3 s){
float x = q.x, y = q.y, z = q.z, w = q.w;
float x2 = x + x;
float y2 = y + y;
float z2 = z + z;
float xx = x * x2;
float xy = x * y2;
float xz = x * z2;
float yy = y * y2;
float yz = y * z2;
float zz = z * z2;
float wx = w * x2;
float wy = w * y2;
float wz = w * z2;
float sx = s.x;
float sy = s.y;
float sz = s.z;
return mat4((1. - (yy + zz)) * sx, (xy + wz) * sx, (xz - wy) * sx, 0,
(xy - wz) * sy, (1. - (xx + zz)) * sy, (yz + wx) * sy, 0,
(xz + wy) * sz, (yz - wx) * sz, (1. - (xx + yy)) * sz, 0,
t.x, t.y, t.z, 1);
}
void scaleMatrix(inout mat4 m, float s){
m[0].xyz *= s;
m[1].xyz *= s;
m[2].xyz *= s;
}
vec4 quatMultiply(vec4 a, vec4 b){
vec4 quat;
quat.x = a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y;
quat.y = a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z;
quat.z = a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x;
quat.w = a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z;
return quat;
}
void rotateVecFromQuat(inout vec3 v, vec4 q){
float ix = q.w * v.x + q.y * v.z - q.z * v.y;
float iy = q.w * v.y + q.z * v.x - q.x * v.z;
float iz = q.w * v.z + q.x * v.y - q.y * v.x;
float iw = -q.x * v.x - q.y * v.y - q.z * v.z;
// calculate result * inverse quat
v.x = ix * q.w + iw * -q.x + iy * -q.z - iz * -q.y;
v.y = iy * q.w + iw * -q.y + iz * -q.x - ix * -q.z;
v.z = iz * q.w + iw * -q.z + ix * -q.y - iy * -q.x;
}
vec3 rotateVecFromAxis(vec3 v, vec3 axis, float theta){
return cos(theta) * v + sin(theta) * cross(v, axis) + (1. - cos(theta)) * dot(v, axis) * axis;
}
vec3 rotateInLocalSpace(vec3 pos, vec3 xAxis, vec3 yAxis, vec3 zAxis, vec4 q){
float z = pos.z;
float x = pos.x;
float y = pos.y;
vec4 viewQuat = quaternionFromAxis(xAxis, yAxis, zAxis);
vec4 rotQuat = quatMultiply(viewQuat, q);
rotateVecFromQuat(pos, rotQuat);
return pos;
}
void rotateCorner(inout vec2 corner, float angle){
float xOS = cos(angle) * corner.x - sin(angle) * corner.y;
float yOS = sin(angle) * corner.x + cos(angle) * corner.y;
corner.x = xOS;
corner.y = yOS;
}

View File

@@ -0,0 +1,9 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
vec3 unpackNormal(vec4 nmap) {
return nmap.xyz * 2.0 - 1.0;
}
vec3 unpackRGBE(vec4 rgbe) {
return rgbe.rgb * pow(2.0, rgbe.a * 255.0 - 128.0);
}