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

Support shadow fade #1960

Merged
merged 14 commits into from
Jan 17, 2024
56 changes: 56 additions & 0 deletions e2e/case/shadow-basic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* @title Shadow basic
* @category Shadow
*/
import {
Animator,
Camera,
DirectLight,
GLTFResource,
MeshRenderer,
PBRMaterial,
PrimitiveMesh,
ShadowResolution,
ShadowType,
Vector3,
WebGLEngine
} from "@galacean/engine";

import { initScreenshot, updateForE2E } from "./.mockForE2E";

WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
engine.canvas.resizeByClientSize();
const scene = engine.sceneManager.activeScene;
const rootEntity = scene.createRootEntity();
scene.shadowResolution = ShadowResolution.Medium;
scene.shadowDistance = 5;
const cameraEntity = rootEntity.createChild("camera_node");
cameraEntity.transform.setPosition(0, 2, 3);
cameraEntity.transform.lookAt(new Vector3(0));
const camera = cameraEntity.addComponent(Camera);
const lightEntity = rootEntity.createChild("light_node");
const light = lightEntity.addComponent(DirectLight);
lightEntity.transform.setPosition(-10, 10, 10);
lightEntity.transform.lookAt(new Vector3(0, 0, 0));

light.shadowType = ShadowType.SoftHigh;

const planeEntity = rootEntity.createChild("plane_node");
const renderer = planeEntity.addComponent(MeshRenderer);
renderer.mesh = PrimitiveMesh.createPlane(engine, 10, 10);
const planeMaterial = new PBRMaterial(engine);
renderer.setMaterial(planeMaterial);

engine.resourceManager
.load<GLTFResource>("https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb")
.then((asset) => {
const { defaultSceneRoot } = asset;
rootEntity.addChild(defaultSceneRoot);

const animator = defaultSceneRoot.getComponent(Animator);
animator.play(asset.animations[0].name);

updateForE2E(engine, 500);
initScreenshot(engine, camera);
});
});
7 changes: 7 additions & 0 deletions e2e/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,12 @@ export const E2E_CONFIG = {
caseFileName: "material-unlit",
threshold: 0.2
}
},
Shadow: {
basic: {
category: "Shadow",
caseFileName: "shadow-basic",
threshold: 0.2
}
}
};
3 changes: 3 additions & 0 deletions e2e/fixtures/originImage/Shadow_shadow-basic.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@
"eslint --fix",
"git add"
]
}
}
},
"repository": "[email protected]:galacean/runtime.git"
}
5 changes: 5 additions & 0 deletions packages/core/src/Scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export class Scene extends EngineObject {
shadowFourCascadeSplits: Vector3 = new Vector3(1.0 / 15, 3.0 / 15.0, 7.0 / 15.0);
/** Max Shadow distance. */
shadowDistance: number = 50;
/**
* Last shadow fade distance in percentage, range [0,1].
* @remarks Value 0 is used for no shadow fade.
*/
shadowFadeBorder: number = 0.1;

/* @internal */
_lightManager: LightManager = new LightManager();
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/shaderlib/mobile_blinnphong_frag.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
shadowAttenuation = 1.0;
#ifdef SCENE_IS_CALCULATE_SHADOWS
shadowAttenuation *= sampleShadowMap();
// int sunIndex = int(scene_ShadowInfo.z);
#endif

DirectLight directionalLight;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ void addTotalDirectRadiance(Geometry geometry, Material material, inout Reflecte
shadowAttenuation = 1.0;
#ifdef SCENE_IS_CALCULATE_SHADOWS
shadowAttenuation *= sampleShadowMap();
// int sunIndex = int(scene_ShadowInfo.z);
#endif

DirectLight directionalLight;
Expand Down
15 changes: 12 additions & 3 deletions packages/core/src/shaderlib/shadow/ShadowFragmentDeclaration.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#include <ShadowCoord>
#endif

// intensity, resolution, sunIndex
uniform vec3 scene_ShadowInfo;
// intensity, null, fadeScale, fadeBias
uniform vec4 scene_ShadowInfo;
uniform vec4 scene_ShadowMapSize;

#ifdef GRAPHICS_API_WEBGL2
Expand Down Expand Up @@ -73,6 +73,13 @@
}
#endif


float getShadowFade(vec3 positionWS){
vec3 camToPixel = positionWS - camera_Position;
float distanceCamToPixel2 = dot(camToPixel, camToPixel);
return saturate( distanceCamToPixel2 * scene_ShadowInfo.z + scene_ShadowInfo.w );
}

float sampleShadowMap() {
#if SCENE_SHADOW_CASCADED_COUNT == 1
vec3 shadowCoord = v_shadowCoord;
Expand All @@ -93,7 +100,9 @@
#if SCENE_SHADOW_TYPE == 3
attenuation = sampleShadowMapFiltered9(scene_ShadowMap, shadowCoord, scene_ShadowMapSize);
#endif
attenuation = mix(1.0, attenuation, scene_ShadowInfo.x);

float shadowFade = getShadowFade(v_pos);
attenuation = mix(1.0, mix(attenuation, 1.0, shadowFade), scene_ShadowInfo.x);
}
return attenuation;
}
Expand Down
Loading