Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bias for planar shadow #16316

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -621,6 +621,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
Loading