Skip to content

Commit

Permalink
add bias for planar shadow (#16316)
Browse files Browse the repository at this point in the history
  • Loading branch information
troublemaker52025 authored Oct 16, 2023
1 parent 590ef33 commit b0c25b0
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 23 deletions.
14 changes: 14 additions & 0 deletions cocos/render-scene/scene/shadows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,18 @@ export class Shadows {
this._distance = val;
}

/**
* @en Positional offset values in planar shading calculations.
* @zh 平面阴影计算中的位置偏移值。
*/
get planeBias (): number {
return this._planeBias;
}

set planeBias (val: number) {
this._planeBias = val;
}

/**
* @en Shadow color.
* @zh 阴影颜色。
Expand Down Expand Up @@ -326,6 +338,7 @@ export class Shadows {
protected _enabled = false;
protected _type = SHADOW_TYPE_NONE;
protected _distance = 0;
protected _planeBias = 1.0;
protected _normal = new Vec3(0, 1, 0);
protected _shadowColor = new Color(0, 0, 0, 76);
protected _size: Vec2 = new Vec2(1024, 1024);
Expand Down Expand Up @@ -356,6 +369,7 @@ export class Shadows {

this.normal = shadowsInfo.planeDirection;
this.distance = shadowsInfo.planeHeight;
this.planeBias = shadowsInfo.planeBias;
this.shadowColor = shadowsInfo.shadowColor;
this.maxReceived = shadowsInfo.maxReceived;
if (shadowsInfo.shadowMapSize !== this._size.x) {
Expand Down
5 changes: 5 additions & 0 deletions cocos/rendering/custom/web-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,11 @@ function setShadowUBOView (setter: WebSetter, camera: Camera | null, layout = 'd
_uboVec.set(_uboVec3.x, _uboVec3.y, _uboVec3.z, -shadowInfo.distance);
setter.offsetVec4(_uboVec, uniformOffset);
}
uniformOffset = setter.getUniformOffset('cc_shadowWHPBInfo', Type.FLOAT4);
if (setter.hasUniform(uniformOffset)) {
_uboVec.set(0, 0, 0, shadowInfo.planeBias);
setter.offsetVec4(_uboVec, uniformOffset);
}
}
if (hasCCShadow) {
setter.setCurrConstant('CCShadow', layout);
Expand Down
2 changes: 2 additions & 0 deletions cocos/rendering/pipeline-ubo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ export class PipelineUBO {
}
} else {
PipelineUBO.updatePlanarNormalAndDistance(shadowInfo, sv);
_vec4ShadowInfo.set(0, 0, 0, shadowInfo.planeBias);
Vec4.toArray(sv, _vec4ShadowInfo, UBOShadow.SHADOW_WIDTH_HEIGHT_PCF_BIAS_INFO_OFFSET);
}

Color.toArray(sv, shadowInfo.shadowColor, UBOShadow.SHADOW_COLOR_OFFSET);
Expand Down
18 changes: 18 additions & 0 deletions cocos/scene-graph/scene-globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,22 @@ export class ShadowsInfo {
return this._distance;
}

/**
* @en Positional offset values in planar shading calculations.
* @zh 平面阴影计算中的位置偏移值。
*/
@tooltip('i18n:shadow.planeBias')
@editable
@type(CCFloat)
@visible(function (this: ShadowsInfo) { return this._type === ShadowType.Planar; })
set planeBias (val: number) {
this._planeBias = val;
if (this._resource) { this._resource.planeBias = val; }
}
get planeBias (): number {
return this._planeBias;
}

/**
* @en get or set shadow max received
* @zh 获取或者设置阴影接收的最大光源数量
Expand Down Expand Up @@ -972,6 +988,8 @@ export class ShadowsInfo {
@serializable
protected _distance = 0;
@serializable
protected _planeBias = 1.0;
@serializable
protected _shadowColor = new Color(0, 0, 0, 76);
@serializable
protected _maxReceived = 4;
Expand Down
4 changes: 2 additions & 2 deletions editor/assets/chunks/common/lighting/functions.chunk
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ vec4 CalculatePlanarShadowPos(vec3 meshWorldPos, vec3 cameraPos, vec3 lightDir,
return vec4(shadowPos, dist);
}
// calculate planar clip pos from world pos
vec4 CalculatePlanarShadowClipPos(vec4 shadowPos, vec3 cameraPos, mat4 matView, mat4 matProj, vec4 nearFar) {
vec4 CalculatePlanarShadowClipPos(vec4 shadowPos, vec3 cameraPos, mat4 matView, mat4 matProj, vec4 nearFar, float bias) {
vec4 camPos = matView * vec4(shadowPos.xyz, 1.0);
// avoid z-fighting with shadow receive plane, add camera bias with perspective correction
// notice that near plane should not be too small, assume near 1, far 1000
float lerpCoef = saturate((nearFar.z < 0.0 ? -camPos.z : camPos.z) / (nearFar.y - nearFar.x));
camPos.z += mix(nearFar.x * 0.01, nearFar.y * EPSILON_LOWP, lerpCoef);
camPos.z += mix(nearFar.x * 0.01, nearFar.y * EPSILON_LOWP * bias, lerpCoef);
return matProj * camPos;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void main()
In.worldPos = shadowPos.xyz;

// Clip Space
In.clipPos = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar);
In.clipPos = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar, cc_shadowWHPBInfo.w);
In.clipPos = SurfacesVertexModifyClipPos(In);

// Other Surfaces Function
Expand Down
2 changes: 1 addition & 1 deletion editor/assets/effects/builtin-unlit.effect
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ CCProgram planar-shadow-vs %{
CCGetWorldMatrixFull(matWorld, matWorldIT);
vec3 worldPos = (matWorld * position).xyz;
vec4 shadowPos = CalculatePlanarShadowPos(worldPos, cc_cameraPos.xyz, cc_mainLitDir.xyz, cc_planarNDInfo);
position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar);
position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar, cc_shadowWHPBInfo.w);
v_dist = shadowPos.w;
return position;
}
Expand Down
2 changes: 1 addition & 1 deletion editor/assets/effects/legacy/standard.effect
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ CCProgram planar-shadow-vs %{
CCGetWorldMatrixFull(matWorld, matWorldIT);
vec3 worldPos = (matWorld * position).xyz;
vec4 shadowPos = CalculatePlanarShadowPos(worldPos, cc_cameraPos.xyz, cc_mainLitDir.xyz, cc_planarNDInfo);
position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar);
position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar, cc_shadowWHPBInfo.w);
v_dist = shadowPos.w;
return position;
}
Expand Down
2 changes: 1 addition & 1 deletion editor/assets/effects/legacy/toon.effect
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ CCProgram planar-shadow-vs %{
CCGetWorldMatrixFull(matWorld, matWorldIT);
vec3 worldPos = (matWorld * position).xyz;
vec4 shadowPos = CalculatePlanarShadowPos(worldPos, cc_cameraPos.xyz, cc_mainLitDir.xyz, cc_planarNDInfo);
position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar);
position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar, cc_shadowWHPBInfo.w);
v_dist = shadowPos.w;
return position;
}
Expand Down
2 changes: 1 addition & 1 deletion editor/assets/effects/pipeline/planar-shadow.effect
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ CCProgram planar-shadow-vs %{
CCGetWorldMatrixFull(matWorld, matWorldIT);
vec3 worldPos = (matWorld * position).xyz;
vec4 shadowPos = CalculatePlanarShadowPos(worldPos, cc_cameraPos.xyz, cc_mainLitDir.xyz, cc_planarNDInfo);
position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar);
position = CalculatePlanarShadowClipPos(shadowPos, cc_cameraPos.xyz, cc_matView, cc_matProj, cc_nearFar, cc_shadowWHPBInfo.w);
v_dist = shadowPos.w;
return position;
}
Expand Down
1 change: 1 addition & 0 deletions editor/i18n/en/localization.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ module.exports = link(mixin({
shadowColor: 'The planar shadow color',
planeDirection: 'The normal vector of the plane which receives shadow.',
planeHeight: 'The height from the origin of the plane which receives shadow.',
planeBias:'Positional offset values in planar shading calculations.',
shadowMapSize: 'Shadowmap resolutions.',
maxReceived: 'Number of the effective light sources that produce shadows.',
},
Expand Down
1 change: 1 addition & 0 deletions editor/i18n/zh/localization.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ module.exports = link(mixin({
shadowColor: '平面阴影颜色',
planeDirection: '阴影接收平面的法线,垂直于阴影,用于调整阴影的倾斜度',
planeHeight: '阴影接收平面距离原点的高度',
planeBias: '平面阴影计算中的位置偏移值',
shadowMapSize: '阴影贴图分辨率,目前支持 Low_256x256、Medium_512x512、High_1024x1024、Ultra_2048x2048 四种精度的纹理',
maxReceived: '产生阴影的有效光源数量',
},
Expand Down
2 changes: 2 additions & 0 deletions native/cocos/renderer/pipeline/PipelineUBO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ void PipelineUBO::updateShadowUBOView(const RenderPipeline *pipeline, ccstd::arr
}
} else if (mainLight && shadowInfo->getType() == scene::ShadowType::PLANAR) {
PipelineUBO::updatePlanarNormalAndDistance(shadowInfo, shadowBufferView);
const float shadowWHPBInfos[4] = {0, 0, 0, shadowInfo->getPlaneBias()};
memcpy(sv.data() + UBOShadow::SHADOW_WIDTH_HEIGHT_PCF_BIAS_INFO_OFFSET, &shadowWHPBInfos, sizeof(shadowWHPBInfos));
}

memcpy(sv.data() + UBOShadow::SHADOW_COLOR_OFFSET, shadowInfo->getShadowColor4f().data(), sizeof(float) * 4);
Expand Down
4 changes: 4 additions & 0 deletions native/cocos/renderer/pipeline/custom/NativeBuiltinUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,10 @@ void setShadowUBOView(
setVec4Impl(data, layoutGraph,
"cc_planarNDInfo",
Vec4(tempVec3.x, tempVec3.y, tempVec3.z, -shadowInfo.getDistance()));
vec4ShadowInfo.set(
0, 0,
0, shadowInfo.getPlaneBias());
setVec4Impl(data, layoutGraph, "cc_shadowWHPBInfo", vec4ShadowInfo);
}
{
const auto &color = shadowInfo.getShadowColor4f();
Expand Down
8 changes: 8 additions & 0 deletions native/cocos/scene/Shadow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ void ShadowsInfo::setPlaneHeight(float val) {
}
}

void ShadowsInfo::setPlaneBias(float val) {
_planeBias = val;
if (_resource != nullptr) {
_resource->setPlaneBias(val);
}
}

void ShadowsInfo::setMaxReceived(uint32_t val) {
_maxReceived = val;
if (_resource != nullptr) {
Expand Down Expand Up @@ -112,6 +119,7 @@ void Shadows::initialize(const ShadowsInfo &shadowsInfo) {
setType(shadowsInfo.getType());
setNormal(shadowsInfo.getPlaneDirection());
setDistance(shadowsInfo.getPlaneHeight());
setPlaneBias(shadowsInfo.getPlaneBias());
setMaxReceived(shadowsInfo.getMaxReceived());
if (fabsf(shadowsInfo.getShadowMapSize() - _size.x) > 0.1F) {
setSize(Vec2(shadowsInfo.getShadowMapSize(), shadowsInfo.getShadowMapSize()));
Expand Down
63 changes: 47 additions & 16 deletions native/cocos/scene/Shadow.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,15 @@ class ShadowsInfo : public RefCounted {
return _distance;
}

/**
* @en Positional offset values in planar shading calculations.
* @zh 平面阴影计算中的位置偏移值
*/
void setPlaneBias(float val);
inline float getPlaneBias() const {
return _planeBias;
}

/**
* @en get or set shadow max received
* @zh 获取或者设置阴影接收的最大光源数量
Expand Down Expand Up @@ -275,14 +284,21 @@ class ShadowsInfo : public RefCounted {
void activate(Shadows *resource);

bool _enabled{false};

ShadowType _type{ShadowType::PLANAR};
Vec3 _normal{0.F, 1.F, 0.F};
float _distance{0.F};
Color _shadowColor{0, 0, 0, 76};

Shadows *_resource{nullptr};

uint32_t _maxReceived{4};

float _distance{0.F};
float _planeBias{1.0F};

Vec2 _size{1024.F, 1024.F};

Shadows *_resource{nullptr};
Vec3 _normal{0.F, 1.F, 0.F};

Color _shadowColor{0, 0, 0, 76};
};

class Shadows final {
Expand Down Expand Up @@ -332,6 +348,13 @@ class Shadows final {
inline float getDistance() const { return _distance; }
inline void setDistance(float val) { _distance = val; }

/**
* @en Positional offset values in planar shading calculations.
* @zh 平面阴影计算中的位置偏移值
*/
inline float getPlaneBias() const { return _planeBias; }
inline void setPlaneBias(float val) { _planeBias = val; }

/**
* @en Shadow color.
* @zh 阴影颜色。
Expand Down Expand Up @@ -398,30 +421,38 @@ class Shadows final {
void createInstanceMaterial();
void createMaterial();

/**
* @en The bounding sphere of the shadow map.
* @zh 用于计算固定区域阴影 Shadow map 的场景包围球.
*/
geometry::Sphere _fixedSphere{0.0F, 0.0F, 0.0F, 0.01F};
bool _enabled{false};
bool _shadowMapDirty{false};

ShadowType _type{ShadowType::NONE};

IntrusivePtr<Material> _material{nullptr};
IntrusivePtr<Material> _instancingMaterial{nullptr};

float _distance{0.F};
float _planeBias{1.0F};

/**
* @en get or set shadow max received.
* @zh 阴影接收的最大灯光数量。
*/
uint32_t _maxReceived{4};

/**
* @en The bounding sphere of the shadow map.
* @zh 用于计算固定区域阴影 Shadow map 的场景包围球.
*/
geometry::Sphere _fixedSphere{0.0F, 0.0F, 0.0F, 0.01F};

Vec2 _size{1024.F, 1024.F};

// public properties of shadow
Vec3 _normal{0.F, 1.F, 0.F};

Color _shadowColor{0, 0, 0, 76};
ccstd::array<float, 4> _shadowColor4f{0.F, 0.F, 0.F, 76.F / 255.F};

Mat4 _matLight;
IntrusivePtr<Material> _material{nullptr};
IntrusivePtr<Material> _instancingMaterial{nullptr};
Vec2 _size{1024.F, 1024.F};
bool _enabled{false};
float _distance{0.F};
ShadowType _type{ShadowType::NONE};
bool _shadowMapDirty{false};
};

} // namespace scene
Expand Down
2 changes: 2 additions & 0 deletions native/tools/swig-config/scene.i
Original file line number Diff line number Diff line change
Expand Up @@ -531,13 +531,15 @@ using namespace cc;
%attribute(cc::scene::ShadowsInfo, cc::Color&, shadowColor, getShadowColor, setShadowColor);
%attribute(cc::scene::ShadowsInfo, cc::Vec3&, planeDirection, getPlaneDirection, setPlaneDirection);
%attribute(cc::scene::ShadowsInfo, float, planeHeight, getPlaneHeight, setPlaneHeight);
%attribute(cc::scene::ShadowsInfo, float, planeBias, getPlaneBias, setPlaneBias);
%attribute(cc::scene::ShadowsInfo, uint32_t, maxReceived, getMaxReceived, setMaxReceived);
%attribute(cc::scene::ShadowsInfo, float, shadowMapSize, getShadowMapSize, setShadowMapSize);

%attribute(cc::scene::Shadows, bool, enabled, isEnabled, setEnabled);
%attribute(cc::scene::Shadows, cc::scene::ShadowType, type, getType, setType);
%attribute(cc::scene::Shadows, cc::Vec3&, normal, getNormal, setNormal);
%attribute(cc::scene::Shadows, float, distance, getDistance, setDistance);
%attribute(cc::scene::Shadows, float, planeBias, getPlaneBias, setPlaneBias);
%attribute(cc::scene::Shadows, cc::Color&, shadowColor, getShadowColor, setShadowColor);
%attribute(cc::scene::Shadows, uint32_t, maxReceived, getMaxReceived, setMaxReceived);
%attribute(cc::scene::Shadows, cc::Vec2&, size, getSize, setSize);
Expand Down

0 comments on commit b0c25b0

Please sign in to comment.