mirror of
https://github.com/smallmain/cocos-enhance-kit.git
synced 2025-01-15 07:21:07 +00:00
101 lines
3.7 KiB
C++
101 lines
3.7 KiB
C++
// 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
|