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 lightmap in pbr workflow #1939

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
52 changes: 52 additions & 0 deletions packages/core/src/material/PBRBaseMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export abstract class PBRBaseMaterial extends BaseMaterial {
private static _clearCoatRoughnessTextureProp = ShaderProperty.getByName("material_ClearCoatRoughnessTexture");
private static _clearCoatNormalTextureProp = ShaderProperty.getByName("material_ClearCoatNormalTexture");

private static _lightmapProp = ShaderProperty.getByName("material_Lightmap");
private static _dirLightmapProp = ShaderProperty.getByName("material_DirLightmap");
private static _lightmapTilingOffsetProp: ShaderProperty = ShaderProperty.getByName("material_LightmapTilingOffset");

/**
* Base color.
*/
Expand Down Expand Up @@ -243,6 +247,52 @@ export abstract class PBRBaseMaterial extends BaseMaterial {
}
}

/**
* Tiling and offset of lightmap textures.
*/
get lightmapTilingOffset(): Vector4 {
return this.shaderData.getVector4(PBRBaseMaterial._lightmapTilingOffsetProp);
}

set lightmapTilingOffset(value: Vector4) {
const tilingOffset = this.shaderData.getVector4(PBRBaseMaterial._lightmapTilingOffsetProp);
if (value !== tilingOffset) {
tilingOffset.copyFrom(value);
}
}

/**
* Lightmap.
*/
get lightmap(): Texture2D {
return <Texture2D>this.shaderData.getTexture(PBRBaseMaterial._lightmapProp);
}

set lightmap(value: Texture2D) {
this.shaderData.setTexture(PBRBaseMaterial._lightmapProp, value);
if (value) {
this.shaderData.enableMacro("MATERIAL_HAS_LIGHTMAP");
} else {
this.shaderData.disableMacro("MATERIAL_HAS_LIGHTMAP");
}
}

/**
* Directional Lightmap.
*/
get dirLightmap(): Texture2D {
return <Texture2D>this.shaderData.getTexture(PBRBaseMaterial._dirLightmapProp);
}

set dirLightmap(value: Texture2D) {
this.shaderData.setTexture(PBRBaseMaterial._dirLightmapProp, value);
if (value) {
this.shaderData.enableMacro("MATERIAL_HAS_DIRLIGHTMAP");
} else {
this.shaderData.disableMacro("MATERIAL_HAS_DIRLIGHTMAP");
}
}

/**
* Create a pbr base material instance.
* @param engine - Engine to which the material belongs
Expand All @@ -266,5 +316,7 @@ export abstract class PBRBaseMaterial extends BaseMaterial {

shaderData.setFloat(PBRBaseMaterial._clearCoatProp, 0);
shaderData.setFloat(PBRBaseMaterial._clearCoatRoughnessProp, 0);

shaderData.setVector4(PBRBaseMaterial._lightmapTilingOffsetProp, new Vector4(1, 1, 0, 0));
}
}
4 changes: 4 additions & 0 deletions packages/core/src/shaderlib/common_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ attribute vec3 POSITION;

uniform vec4 material_TilingOffset;

#ifdef MATERIAL_HAS_LIGHTMAP
uniform vec4 material_LightmapTilingOffset;
#endif


#ifndef MATERIAL_OMIT_NORMAL
#ifdef RENDERER_HAS_NORMAL
Expand Down
13 changes: 13 additions & 0 deletions packages/core/src/shaderlib/pbr/ibl_frag_define.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ vec3 getLightProbeIrradiance(vec3 sh[9], vec3 normal){

}

vec3 DecodeDirectionalLightmap(vec3 color, vec4 dirTex, vec3 normalWorld) {
// In directional (non-specular) mode Enlighten bakes dominant light direction
// in a way, that using it for half Lambert and then dividing by a "rebalancing coefficient"
// gives a result close to plain diffuse response lightmaps, but normalmapped.

// Note that dir is not unit length on purpose. Its length is "directionality", like
// for the directional specular lightmaps.

float halfLambert = dot(normalWorld, dirTex.xyz - 0.5) + 0.5;

return color * halfLambert / max(1e-4, dirTex.w);
}

// ------------------------Specular------------------------

// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile
Expand Down
22 changes: 17 additions & 5 deletions packages/core/src/shaderlib/pbr/pbr_frag.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,28 @@ initMaterial(material, geometry);
addTotalDirectRadiance(geometry, material, reflectedLight);

// IBL diffuse
#ifdef SCENE_USE_SH
vec3 irradiance = getLightProbeIrradiance(scene_EnvSH, geometry.normal);
#ifdef MATERIAL_HAS_LIGHTMAP
vec4 lightmapColor= texture2D(material_Lightmap, v_lightmapUV);
vec3 irradiance = RGBMToLinear(lightmapColor, 5.0).rgb;
#ifdef MATERIAL_HAS_DIRLIGHTMAP
vec4 dirLightmapColor = texture2D (material_DirLightmap, v_lightmapUV);
irradiance = DecodeDirectionalLightmap (irradiance, dirLightmapColor, geometry.normal);
#endif
#ifdef ENGINE_IS_COLORSPACE_GAMMA
irradiance = linearToGamma(vec4(irradiance, 1.0)).rgb;
#endif
irradiance *= scene_EnvMapLight.diffuseIntensity;
#else
vec3 irradiance = scene_EnvMapLight.diffuse * scene_EnvMapLight.diffuseIntensity;
irradiance *= PI;
#ifdef SCENE_USE_SH
vec3 irradiance = getLightProbeIrradiance(scene_EnvSH, geometry.normal);
#ifdef ENGINE_IS_COLORSPACE_GAMMA
irradiance = linearToGamma(vec4(irradiance, 1.0)).rgb;
#endif
#else
vec3 irradiance = scene_EnvMapLight.diffuse * PI; // spherical convolution
#endif
#endif
irradiance *= scene_EnvMapLight.diffuseIntensity;


reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );

Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/shaderlib/pbr/pbr_frag_define.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ uniform float material_OcclusionTextureCoord;
uniform sampler2D material_OcclusionTexture;
#endif

#ifdef MATERIAL_HAS_LIGHTMAP
uniform sampler2D material_Lightmap;
#ifdef MATERIAL_HAS_DIRLIGHTMAP
uniform sampler2D material_DirLightmap;
#endif
#endif

// Runtime
struct ReflectedLight {
vec3 directDiffuse;
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/shaderlib/uv_share.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ varying vec2 v_uv;

#ifdef RENDERER_HAS_UV1
varying vec2 v_uv1;
#endif

#ifdef MATERIAL_HAS_LIGHTMAP
varying vec2 v_lightmapUV;
#endif
4 changes: 4 additions & 0 deletions packages/core/src/shaderlib/uv_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@

#ifdef MATERIAL_NEED_TILING_OFFSET
v_uv = v_uv * material_TilingOffset.xy + material_TilingOffset.zw;
#endif

#ifdef MATERIAL_HAS_LIGHTMAP
v_lightmapUV = v_uv1 * material_LightmapTilingOffset.xy + material_LightmapTilingOffset.zw;
#endif