mirror of
https://github.com/4ian/GDevelop.git
synced 2026-10-12 02:01:17 +00:00
Replace the fitted shadows boolean by a shadow rendering mode choice
"Fitted to camera view" is used by new projects and new directional lights. "Centered around camera" stays the mode of lights saved before, as the legacy mode. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01R21PyxoRnR5h7u9NQX66ZG
This commit is contained in:
@@ -414,6 +414,9 @@ namespace gdjs {
|
||||
if (parameterName === 'top') {
|
||||
this._top = value;
|
||||
}
|
||||
if (parameterName === 'shadowRenderingMode') {
|
||||
this._isShadowFittedToCamera = value === 'fittedToCameraView';
|
||||
}
|
||||
if (parameterName === 'shadowQuality') {
|
||||
if (value === 'low' && this._shadowMapSize !== 512) {
|
||||
this._shadowMapSize = 512;
|
||||
@@ -443,8 +446,6 @@ namespace gdjs {
|
||||
updateBooleanParameter(parameterName: string, value: boolean): void {
|
||||
if (parameterName === 'isCastingShadow') {
|
||||
this._light.castShadow = value;
|
||||
} else if (parameterName === 'isShadowFittedToCamera') {
|
||||
this._isShadowFittedToCamera = value;
|
||||
}
|
||||
}
|
||||
getNetworkSyncData(): DirectionalLightFilterNetworkSyncData {
|
||||
|
||||
@@ -2299,15 +2299,20 @@ module.exports = {
|
||||
.setType('choice')
|
||||
.setGroup(_('Shadows'));
|
||||
properties
|
||||
.getOrCreate('isShadowFittedToCamera')
|
||||
.setValue('false')
|
||||
.setLabel(_('Fit shadows to the camera view'))
|
||||
.getOrCreate('shadowRenderingMode')
|
||||
.setValue('centeredAroundCamera')
|
||||
.addChoice('fittedToCameraView', _('Fitted to camera view (default)'))
|
||||
.addChoice(
|
||||
'centeredAroundCamera',
|
||||
_("Centered around camera (legacy - don't use anymore)")
|
||||
)
|
||||
.setLabel(_('Rendering mode'))
|
||||
.setDescription(
|
||||
_(
|
||||
'Draw shadows only for what the camera sees, up to the shadow distance, for sharper shadows. Always recommended: this will become the only mode in the future.'
|
||||
'Fitted to camera view draws shadows only for what the camera sees, up to the shadow distance, for sharper shadows. The legacy mode will be removed in the future.'
|
||||
)
|
||||
)
|
||||
.setType('boolean')
|
||||
.setType('choice')
|
||||
.setGroup(_('Shadows'));
|
||||
properties
|
||||
.getOrCreate('shadowDistance')
|
||||
@@ -2315,7 +2320,7 @@ module.exports = {
|
||||
.setLabel(_('Shadow distance'))
|
||||
.setDescription(
|
||||
_(
|
||||
'Distance from the camera up to which shadows are drawn, when they are fitted to the camera view. The smaller it is, the sharper shadows are.'
|
||||
'Distance from the camera up to which shadows are drawn. The smaller it is, the sharper shadows are. Not used by the legacy rendering mode.'
|
||||
)
|
||||
)
|
||||
.setType('number')
|
||||
@@ -2362,7 +2367,7 @@ module.exports = {
|
||||
.setLabel(_('Shadow frustum size'))
|
||||
.setDescription(
|
||||
_(
|
||||
'Size of the area around the camera where shadows are drawn, when they are not fitted to the camera view. Prefer fitting shadows to the camera view, which gives sharper shadows.'
|
||||
'Size of the area around the camera where shadows are drawn. Only used by the legacy rendering mode.'
|
||||
)
|
||||
)
|
||||
.setType('number')
|
||||
|
||||
@@ -3,17 +3,14 @@
|
||||
describe('Scene3D::DirectionalLight', () => {
|
||||
/**
|
||||
* @param {'Z+' | 'Y-'} top
|
||||
* @param {{isShadowFittedToCamera?: boolean}} [options]
|
||||
* @param {'fittedToCameraView' | 'centeredAroundCamera'} shadowRenderingMode
|
||||
* @returns {EffectData}
|
||||
*/
|
||||
const makeDirectionalLightEffectData = (
|
||||
top,
|
||||
{ isShadowFittedToCamera = false } = {}
|
||||
) => ({
|
||||
const makeDirectionalLightEffectData = (top, shadowRenderingMode) => ({
|
||||
name: 'Sun',
|
||||
effectType: 'Scene3D::DirectionalLight',
|
||||
stringParameters: { top, shadowQuality: 'medium' },
|
||||
booleanParameters: { isCastingShadow: true, isShadowFittedToCamera },
|
||||
stringParameters: { top, shadowQuality: 'medium', shadowRenderingMode },
|
||||
booleanParameters: { isCastingShadow: true },
|
||||
doubleParameters: {
|
||||
// A vertical light is a special case for the "Y-" top.
|
||||
elevation: top === 'Y-' ? 90 : 37,
|
||||
@@ -104,10 +101,13 @@ describe('Scene3D::DirectionalLight', () => {
|
||||
};
|
||||
|
||||
for (const top of /** @type {Array<'Z+' | 'Y-'>} */ (['Z+', 'Y-'])) {
|
||||
for (const isShadowFittedToCamera of [false, true]) {
|
||||
it(`keeps shadow map texels in place when the camera moves (top: ${top}, fitted to camera: ${isShadowFittedToCamera})`, () => {
|
||||
for (const shadowRenderingMode of /** @type {Array<'fittedToCameraView' | 'centeredAroundCamera'>} */ ([
|
||||
'fittedToCameraView',
|
||||
'centeredAroundCamera',
|
||||
])) {
|
||||
it(`keeps shadow map texels in place when the camera moves (top: ${top}, rendering mode: ${shadowRenderingMode})`, () => {
|
||||
const layer = make3DLayerWithEffect(
|
||||
makeDirectionalLightEffectData(top, { isShadowFittedToCamera })
|
||||
makeDirectionalLightEffectData(top, shadowRenderingMode)
|
||||
);
|
||||
const light = getDirectionalLight(layer);
|
||||
const shadowCaster = new THREE.Mesh(
|
||||
@@ -136,7 +136,7 @@ describe('Scene3D::DirectionalLight', () => {
|
||||
|
||||
it('covers what the camera sees up to the shadow distance, with a smaller shadow map area', () => {
|
||||
const layer = make3DLayerWithEffect(
|
||||
makeDirectionalLightEffectData('Z+', { isShadowFittedToCamera: true })
|
||||
makeDirectionalLightEffectData('Z+', 'fittedToCameraView')
|
||||
);
|
||||
const light = getDirectionalLight(layer);
|
||||
const threeCamera = layer.getRenderer().getThreeCamera();
|
||||
@@ -186,7 +186,9 @@ describe('Scene3D::DirectionalLight', () => {
|
||||
});
|
||||
|
||||
it('applies the shadow intensity and softness', () => {
|
||||
const layer = make3DLayerWithEffect(makeDirectionalLightEffectData('Z+'));
|
||||
const layer = make3DLayerWithEffect(
|
||||
makeDirectionalLightEffectData('Z+', 'centeredAroundCamera')
|
||||
);
|
||||
const light = getDirectionalLight(layer);
|
||||
expect(light.shadow.intensity).to.be(0.6);
|
||||
expect(light.shadow.radius).to.be(2.5);
|
||||
@@ -198,7 +200,9 @@ describe('Scene3D::DirectionalLight', () => {
|
||||
});
|
||||
|
||||
it('applies a shadow frustum size changed after the first rendering', () => {
|
||||
const layer = make3DLayerWithEffect(makeDirectionalLightEffectData('Z+'));
|
||||
const layer = make3DLayerWithEffect(
|
||||
makeDirectionalLightEffectData('Z+', 'centeredAroundCamera')
|
||||
);
|
||||
const light = getDirectionalLight(layer);
|
||||
renderLayer(layer);
|
||||
// The world scale is 100.
|
||||
|
||||
@@ -84,10 +84,10 @@ export const enumerateEffectNames = (
|
||||
* them.
|
||||
*/
|
||||
const parameterValuesForNewEffects: {
|
||||
[effectType: string]: {| booleanParameters: { [string]: boolean } |},
|
||||
[effectType: string]: {| stringParameters: { [string]: string } |},
|
||||
} = {
|
||||
'Scene3D::DirectionalLight': {
|
||||
booleanParameters: { isShadowFittedToCamera: true },
|
||||
stringParameters: { shadowRenderingMode: 'fittedToCameraView' },
|
||||
},
|
||||
};
|
||||
|
||||
@@ -117,10 +117,10 @@ export const setEffectDefaultParameters = (
|
||||
|
||||
const parameterValues = parameterValuesForNewEffects[effect.getEffectType()];
|
||||
if (parameterValues) {
|
||||
Object.keys(parameterValues.booleanParameters).forEach(parameterName => {
|
||||
effect.setBooleanParameter(
|
||||
Object.keys(parameterValues.stringParameters).forEach(parameterName => {
|
||||
effect.setStringParameter(
|
||||
parameterName,
|
||||
parameterValues.booleanParameters[parameterName]
|
||||
parameterValues.stringParameters[parameterName]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -57,7 +57,10 @@ export const addDefaultLightToLayer = (layer: gdLayer): void => {
|
||||
directionalLight.setDoubleParameter('minimumShadowBias', 0);
|
||||
directionalLight.setDoubleParameter('distanceFromCamera', 1500);
|
||||
directionalLight.setDoubleParameter('frustumSize', 4000);
|
||||
directionalLight.setBooleanParameter('isShadowFittedToCamera', true);
|
||||
directionalLight.setStringParameter(
|
||||
'shadowRenderingMode',
|
||||
'fittedToCameraView'
|
||||
);
|
||||
directionalLight.setDoubleParameter('shadowDistance', 2000);
|
||||
|
||||
const ambientLight = layer
|
||||
|
||||
Reference in New Issue
Block a user