mirror of
https://github.com/galacean/engine.git
synced 2026-05-31 15:51:33 +08:00
@@ -4,8 +4,10 @@
|
||||
*/
|
||||
import {
|
||||
AmbientLight,
|
||||
AmbientOcclusionQuality,
|
||||
AssetType,
|
||||
BackgroundMode,
|
||||
BlendFactor,
|
||||
Camera,
|
||||
Color,
|
||||
DirectLight,
|
||||
@@ -13,20 +15,33 @@ import {
|
||||
MeshRenderer,
|
||||
PBRMaterial,
|
||||
PrimitiveMesh,
|
||||
RenderQueueType,
|
||||
Shader,
|
||||
SkyBoxMaterial,
|
||||
AmbientOcclusionQuality,
|
||||
Vector3,
|
||||
WebGLEngine,
|
||||
WebGLMode
|
||||
} from "@galacean/engine";
|
||||
import { PBRSource, registerIncludes } from "@galacean/engine-shader";
|
||||
import { ShaderLab } from "@galacean/engine-shaderlab";
|
||||
import { initScreenshot, updateForE2E } from "./.mockForE2E";
|
||||
|
||||
Logger.enable();
|
||||
WebGLEngine.create({ canvas: "canvas", graphicDeviceOptions: { webGLMode: WebGLMode.WebGL1 } }).then((engine) => {
|
||||
|
||||
registerIncludes();
|
||||
|
||||
// Create engine
|
||||
WebGLEngine.create({
|
||||
canvas: "canvas",
|
||||
shaderLab: new ShaderLab(),
|
||||
graphicDeviceOptions: { webGLMode: WebGLMode.WebGL1 }
|
||||
}).then((engine) => {
|
||||
engine.canvas.resizeByClientSize(2);
|
||||
|
||||
const scene = engine.sceneManager.activeScene;
|
||||
const rootEntity = scene.createRootEntity();
|
||||
const { ambientLight, background } = scene;
|
||||
|
||||
const pbrShader = Shader.create(PBRSource);
|
||||
|
||||
// camera
|
||||
const cameraEntity = rootEntity.createChild("camera_node");
|
||||
@@ -34,46 +49,62 @@ WebGLEngine.create({ canvas: "canvas", graphicDeviceOptions: { webGLMode: WebGLM
|
||||
const camera = cameraEntity.addComponent(Camera);
|
||||
|
||||
scene.ambientOcclusion.enabled = true;
|
||||
// scene.ambientOcclusion.radius = 0.4;
|
||||
// scene.ambientOcclusion.intensity = 3;
|
||||
// scene.ambientOcclusion.power = 1.0;
|
||||
// scene.ambientOcclusion.bias = 0.0005;
|
||||
// scene.ambientOcclusion.bilateralThreshold = 0.01;
|
||||
scene.ambientOcclusion.quality = AmbientOcclusionQuality.High;
|
||||
|
||||
const lightNode = rootEntity.createChild("light_node");
|
||||
lightNode.addComponent(DirectLight).color = new Color(1, 1, 1);
|
||||
lightNode.transform.rotate(new Vector3(-45, 60, 0));
|
||||
|
||||
const { background } = scene;
|
||||
const sky = background.sky;
|
||||
const skyMaterial = new SkyBoxMaterial(engine);
|
||||
background.mode = BackgroundMode.Sky;
|
||||
sky.material = skyMaterial;
|
||||
sky.mesh = PrimitiveMesh.createCuboid(engine, 1, 1, 1);
|
||||
|
||||
// Sphere
|
||||
const sphereMaterial = new PBRMaterial(engine);
|
||||
sphereMaterial.baseColor = new Color(1, 1, 1, 1);
|
||||
sphereMaterial.shader = pbrShader;
|
||||
sphereMaterial.shaderData.setInt("depthWriteEnabled", 1);
|
||||
const sphere = rootEntity.createChild("sphere");
|
||||
const { transform } = sphere;
|
||||
transform.setPosition(0, 1, 0);
|
||||
transform.setRotation(45, 45, 0);
|
||||
sphere.transform.setPosition(0, 1, 0);
|
||||
sphere.transform.setRotation(45, 45, 0);
|
||||
const meshRenderer = sphere.addComponent(MeshRenderer);
|
||||
meshRenderer.mesh = PrimitiveMesh.createSubdivisionSurfaceSphere(engine);
|
||||
meshRenderer.setMaterial(sphereMaterial);
|
||||
|
||||
const box = rootEntity.createChild("box");
|
||||
// Box
|
||||
const boxMaterial = new PBRMaterial(engine);
|
||||
boxMaterial.baseColor = new Color(1, 1, 1, 1);
|
||||
boxMaterial.shader = pbrShader;
|
||||
boxMaterial.shaderData.setInt("depthWriteEnabled", 1);
|
||||
const box = rootEntity.createChild("box");
|
||||
box.transform.setPosition(1, 0.9, 0.1);
|
||||
box.transform.setRotation(30, 30, 0);
|
||||
const boxMeshRenderer = box.addComponent(MeshRenderer);
|
||||
boxMeshRenderer.mesh = PrimitiveMesh.createCuboid(engine);
|
||||
boxMeshRenderer.setMaterial(boxMaterial);
|
||||
|
||||
const capsule = rootEntity.createChild("capsule");
|
||||
// Capsule (transparent)
|
||||
const capsuleMaterial = new PBRMaterial(engine);
|
||||
capsuleMaterial.isTransparent = true;
|
||||
capsuleMaterial.baseColor = new Color(1, 1, 1, 0.5);
|
||||
capsuleMaterial.isTransparent = true;
|
||||
capsuleMaterial.shader = pbrShader;
|
||||
{
|
||||
const shaderData = capsuleMaterial.shaderData;
|
||||
shaderData.setInt("depthWriteEnabled", 1);
|
||||
shaderData.setInt("blendEnabled", 1);
|
||||
shaderData.setInt("renderQueueType", RenderQueueType.Transparent);
|
||||
shaderData.enableMacro("MATERIAL_IS_TRANSPARENT");
|
||||
|
||||
shaderData.setInt("sourceColorBlendFactor", BlendFactor.SourceAlpha);
|
||||
shaderData.setInt("destinationColorBlendFactor", BlendFactor.OneMinusSourceAlpha);
|
||||
shaderData.setInt("sourceAlphaBlendFactor", BlendFactor.One);
|
||||
shaderData.setInt("destinationAlphaBlendFactor", BlendFactor.OneMinusSourceAlpha);
|
||||
}
|
||||
|
||||
const capsule = rootEntity.createChild("capsule");
|
||||
capsule.transform.setPosition(1, 0.9, 0.1);
|
||||
capsule.transform.setRotation(30, 30, 0);
|
||||
const capsuleMeshRenderer = capsule.addComponent(MeshRenderer);
|
||||
|
||||
@@ -69,10 +69,26 @@ vec4 outputSRGBCorrection(vec4 linearIn){
|
||||
|
||||
vec4 camera_DepthBufferParams;
|
||||
|
||||
float remapDepthBufferLinear01(float z){
|
||||
return 1.0/ (camera_DepthBufferParams.x * z + camera_DepthBufferParams.y);
|
||||
float remapDepthBufferLinear01(float depth){
|
||||
return 1.0 / (camera_DepthBufferParams.x * depth + camera_DepthBufferParams.y);
|
||||
}
|
||||
|
||||
float remapDepthBufferEyeDepth(float depth){
|
||||
#ifdef CAMERA_ORTHOGRAPHIC
|
||||
return camera_ProjectionParams.y + (camera_ProjectionParams.z - camera_ProjectionParams.y) * depth;
|
||||
#else
|
||||
return 1.0 / (camera_DepthBufferParams.z * depth + camera_DepthBufferParams.w);
|
||||
#endif
|
||||
}
|
||||
|
||||
// From Next Generation Post Processing in Call of Duty: Advanced Warfare [Jimenez 2014]
|
||||
// http://advances.realtimerendering.com/s2014/index.html
|
||||
// sampleCoord must not be normalized (e.g. window coordinates)
|
||||
float interleavedGradientNoise(vec2 sampleCoord)
|
||||
{
|
||||
const vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189);
|
||||
return fract(magic.z * fract(dot(sampleCoord, magic.xy)));
|
||||
}
|
||||
|
||||
#ifdef GRAPHICS_API_WEBGL2
|
||||
#define INVERSE_MAT(mat) inverse(mat)
|
||||
|
||||
@@ -90,6 +90,7 @@ Shader "PBRShaderName" {
|
||||
|
||||
SubShader "Default" {
|
||||
UsePass "pbr/Default/ShadowCaster"
|
||||
UsePass "pbr/Default/DepthOnly"
|
||||
|
||||
Pass "Forward Pass" {
|
||||
Tags { pipelineStage = "Forward"}
|
||||
|
||||
@@ -26,6 +26,7 @@ struct SurfaceData{
|
||||
|
||||
// geometry
|
||||
vec3 position;
|
||||
vec4 positionCS;
|
||||
vec3 normal;
|
||||
|
||||
#ifdef NEED_TANGENT
|
||||
@@ -426,6 +427,17 @@ vec3 envBRDFApprox(vec3 f0, float f90, float roughness, float dotNV ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SCENE_ENABLE_AMBIENT_OCCLUSION
|
||||
sampler2D camera_AOTexture;
|
||||
float evaluateAmbientOcclusion(vec2 uv){
|
||||
#ifdef MATERIAL_IS_TRANSPARENT
|
||||
return 1.0;
|
||||
#else
|
||||
return texture2D(camera_AOTexture, uv).r;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void initBSDFData(SurfaceData surfaceData, out BSDFData bsdfData){
|
||||
vec3 albedoColor = surfaceData.albedoColor;
|
||||
float metallic = surfaceData.metallic;
|
||||
@@ -463,6 +475,11 @@ void initBSDFData(SurfaceData surfaceData, out BSDFData bsdfData){
|
||||
|
||||
bsdfData.diffuseAO = surfaceData.ambientOcclusion;
|
||||
|
||||
#ifdef SCENE_ENABLE_AMBIENT_OCCLUSION
|
||||
float ambientAO = evaluateAmbientOcclusion((surfaceData.positionCS.xy / surfaceData.positionCS.w) * 0.5 + 0.5);
|
||||
bsdfData.diffuseAO = min(bsdfData.diffuseAO, ambientAO);
|
||||
#endif
|
||||
|
||||
#ifdef MATERIAL_ENABLE_CLEAR_COAT
|
||||
bsdfData.clearCoatRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(surfaceData.clearCoatRoughness + getAARoughnessFactor(surfaceData.clearCoatNormal), 1.0));
|
||||
bsdfData.clearCoatSpecularColor = vec3(0.04);
|
||||
|
||||
@@ -55,6 +55,8 @@ Varyings PBRVertex(Attributes attributes) {
|
||||
|
||||
gl_Position = renderer_MVPMat * vertexInputs.positionOS;
|
||||
|
||||
varyings.positionCS = gl_Position;
|
||||
|
||||
return varyings;
|
||||
}
|
||||
|
||||
|
||||
@@ -174,6 +174,7 @@ SurfaceData getSurfaceData(Varyings v, vec2 aoUV, bool isFrontFacing){
|
||||
|
||||
// Geometry
|
||||
surfaceData.position = v.positionWS;
|
||||
surfaceData.positionCS = v.positionCS;
|
||||
|
||||
#ifdef CAMERA_ORTHOGRAPHIC
|
||||
surfaceData.viewDir = -camera_Forward;
|
||||
|
||||
@@ -45,10 +45,10 @@ vec3 getLightProbeRadiance(SurfaceData surfaceData, vec3 normal, float roughness
|
||||
|
||||
float evaluateSpecularOcclusion(float dotNV, float diffuseAO, float roughness){
|
||||
float specularAOFactor = 1.0;
|
||||
#if defined(MATERIAL_HAS_OCCLUSION_TEXTURE) && defined(SCENE_USE_SPECULAR_ENV)
|
||||
#if (defined(MATERIAL_HAS_OCCLUSION_TEXTURE) || defined(SCENE_ENABLE_AMBIENT_OCCLUSION)) && defined(SCENE_USE_SPECULAR_ENV)
|
||||
specularAOFactor = saturate( pow(dotNV + diffuseAO, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + diffuseAO );
|
||||
#endif
|
||||
return specularAOFactor;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -29,6 +29,8 @@ struct Varyings{
|
||||
#if defined(NEED_CALCULATE_SHADOWS) && (SCENE_SHADOW_CASCADED_COUNT == 1)
|
||||
vec3 shadowCoord;
|
||||
#endif
|
||||
|
||||
vec4 positionCS;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -34,17 +34,18 @@ describe("ShaderLab", async () => {
|
||||
const shader = shaderLabVerbose._parseShaderSource(PBRSource);
|
||||
const subShader = shader.subShaders[0];
|
||||
const passList = subShader.passes;
|
||||
const pass1 = passList[1];
|
||||
const pass1 = passList[2];
|
||||
|
||||
// shader name
|
||||
expect(shader.name).to.equal("PBRShaderName");
|
||||
expect(subShader.name).to.equal("Default");
|
||||
expect(pass1.name).to.equal("Forward Pass");
|
||||
expect(passList.length).to.eq(2);
|
||||
expect(passList.length).to.eq(3);
|
||||
|
||||
// Pass
|
||||
expect(passList[0].isUsePass).to.be.true;
|
||||
expect(passList[1].name).eq("Forward Pass");
|
||||
expect(passList[1].isUsePass).to.be.true;
|
||||
expect(passList[2].name).eq("Forward Pass");
|
||||
|
||||
// renderState
|
||||
expect(pass1.renderStates).not.be.null;
|
||||
|
||||
Reference in New Issue
Block a user