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

Feat: support pbr ior #694

Closed
wants to merge 17 commits into from
187 changes: 186 additions & 1 deletion packages/core/src/material/PBRBaseMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,22 @@ export abstract class PBRBaseMaterial extends BaseMaterial {
private static _normalTextureProp = Shader.getPropertyByName("u_normalTexture");
private static _normalTextureIntensityProp = Shader.getPropertyByName("u_normalIntensity");
private static _occlusionTextureIntensityProp = Shader.getPropertyByName("u_occlusionStrength");

private static _emissiveTextureProp = Shader.getPropertyByName("u_emissiveSampler");
private static _occlusionTextureProp = Shader.getPropertyByName("u_occlusionSampler");

private static _clearcoatProp = Shader.getPropertyByName("u_clearcoat");
private static _clearcoatTextureProp = Shader.getPropertyByName("u_clearcoatTexture");
private static _clearcoatRoughnessProp = Shader.getPropertyByName("u_clearcoatRoughness");
private static _clearcoatRoughnessTextureProp = Shader.getPropertyByName("u_clearcoatRoughnessTexture");
private static _clearcoatNormalTextureProp = Shader.getPropertyByName("u_clearcoatNormalTexture");

private static _sheenColor = Shader.getPropertyByName("u_sheenColor");
private static _sheenColorTexture = Shader.getPropertyByName("u_sheenColorTexture");
private static _sheenRoughness = Shader.getPropertyByName("u_sheenRoughness");
private static _sheenRoughnessTexture = Shader.getPropertyByName("u_sheenRoughnessTexture");

private _sheenEnabled: boolean = false;

/**
* Base color.
*/
Expand Down Expand Up @@ -148,6 +160,163 @@ export abstract class PBRBaseMaterial extends BaseMaterial {
}
}

/**
* The clearcoat layer intensity, default 0.
*/
get clearcoat(): number {
return this.shaderData.getFloat(PBRBaseMaterial._clearcoatProp);
}

set clearcoat(value: number) {
this.shaderData.setFloat(PBRBaseMaterial._clearcoatProp, value);

if (value === 0) {
this.shaderData.disableMacro("CLEARCOAT");
} else {
this.shaderData.enableMacro("CLEARCOAT");
}
}

/**
* The clearcoat layer intensity texture.
*/
get clearcoatTexture(): Texture2D {
return <Texture2D>this.shaderData.getTexture(PBRBaseMaterial._clearcoatTextureProp);
}

set clearcoatTexture(value: Texture2D) {
this.shaderData.setTexture(PBRBaseMaterial._clearcoatTextureProp, value);

if (value) {
this.shaderData.enableMacro("HAS_CLEARCOATTEXTURE");
} else {
this.shaderData.disableMacro("HAS_CLEARCOATTEXTURE");
}
}

/**
* The clearcoat layer roughness, default 0.
*/
get clearcoatRoughness(): number {
return this.shaderData.getFloat(PBRBaseMaterial._clearcoatRoughnessProp);
}

set clearcoatRoughness(value: number) {
this.shaderData.setFloat(PBRBaseMaterial._clearcoatRoughnessProp, value);
}

/**
* The clearcoat layer roughness texture.
*/
get clearcoatRoughnessTexture(): Texture2D {
return <Texture2D>this.shaderData.getTexture(PBRBaseMaterial._clearcoatRoughnessTextureProp);
}

set clearcoatRoughnessTexture(value: Texture2D) {
this.shaderData.setTexture(PBRBaseMaterial._clearcoatRoughnessTextureProp, value);

if (value) {
this.shaderData.enableMacro("HAS_CLEARCOATROUGHNESSTEXTURE");
} else {
this.shaderData.disableMacro("HAS_CLEARCOATROUGHNESSTEXTURE");
}
}

/**
* The clearcoat normal map texture.
*/
get clearcoatNormalTexture(): Texture2D {
return <Texture2D>this.shaderData.getTexture(PBRBaseMaterial._clearcoatNormalTextureProp);
}

set clearcoatNormalTexture(value: Texture2D) {
this.shaderData.setTexture(PBRBaseMaterial._clearcoatNormalTextureProp, value);

if (value) {
this.shaderData.enableMacro("HAS_CLEARCOATNORMALTEXTURE");
} else {
this.shaderData.disableMacro("HAS_CLEARCOATNORMALTEXTURE");
}
}

/**
* Sheen enabled.
* @remark
*/
get sheenEnabled(): boolean {
return this._sheenEnabled;
}

set sheenEnabled(value: boolean) {
this._sheenEnabled = value;

if (value) {
this.shaderData.enableMacro("SHEEN");
} else {
this.shaderData.disableMacro("SHEEN");
}
}

/**
* Sheen color, default [0,0,0].
*/
get sheenColor(): Color {
return this.shaderData.getColor(PBRBaseMaterial._sheenColor);
}

set sheenColor(value: Color) {
const baseColor = this.shaderData.getColor(PBRBaseMaterial._sheenColor);

if (value !== baseColor) {
value.cloneTo(baseColor);
}
}

/**
* The sheen color texture.
*/
get sheenColorTexture(): Texture2D {
return <Texture2D>this.shaderData.getTexture(PBRBaseMaterial._sheenColorTexture);
}

set sheenColorTexture(value: Texture2D) {
this.shaderData.setTexture(PBRBaseMaterial._sheenColorTexture, value);

if (value) {
this.shaderData.enableMacro("HAS_SHEENCOLORTEXTURE");
} else {
this.shaderData.disableMacro("HAS_SHEENCOLORTEXTURE");
}
}

/**
* Sheen roughness, default 0.
*/
get sheenRoughness(): number {
return this.shaderData.getFloat(PBRBaseMaterial._sheenRoughness);
}

set sheenRoughness(value: number) {
this.shaderData.setFloat(PBRBaseMaterial._sheenRoughness, value);
}

/**
* The sheen roughness texture.
*/
get sheenRoughnessTexture(): Texture2D {
return <Texture2D>this.shaderData.getTexture(PBRBaseMaterial._sheenRoughnessTexture);
}

set sheenRoughnessTexture(value: Texture2D) {
this.shaderData.setTexture(PBRBaseMaterial._sheenRoughnessTexture, value);

if (value) {
this.shaderData.enableMacro("HAS_SHEENROUGHNESSTEXTURE");
} else {
this.shaderData.disableMacro("HAS_SHEENROUGHNESSTEXTURE");
}
}

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

shaderData.setFloat(PBRBaseMaterial._normalTextureIntensityProp, 1);
shaderData.setFloat(PBRBaseMaterial._occlusionTextureIntensityProp, 1);

shaderData.setFloat(PBRBaseMaterial._clearcoatProp, 0);
shaderData.setFloat(PBRBaseMaterial._clearcoatRoughnessProp, 0);

shaderData.setColor(PBRBaseMaterial._sheenColor, new Color(0, 0, 0, 1));
shaderData.setFloat(PBRBaseMaterial._sheenRoughness, 0);
}

/**
* @override
* Clone to the target material.
* @param target - target material
*/
cloneTo(target: PBRBaseMaterial): void {
super.cloneTo(target);
target._sheenEnabled = this._sheenEnabled;
}
}
25 changes: 21 additions & 4 deletions packages/core/src/material/PBRMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ export class PBRMaterial extends PBRBaseMaterial {
private static _metallicProp = Shader.getPropertyByName("u_metal");
private static _roughnessProp = Shader.getPropertyByName("u_roughness");
private static _metallicRoughnessTextureProp = Shader.getPropertyByName("u_metallicRoughnessSampler");
private static _iorProp = Shader.getPropertyByName("u_ior");

/**
* Metallic.
* Metallic, default 1.
*/
get metallic(): number {
return this.shaderData.getFloat(PBRMaterial._metallicProp);
Expand All @@ -23,7 +24,7 @@ export class PBRMaterial extends PBRBaseMaterial {
}

/**
* Roughness.
* Roughness, default 1.
*/
get roughness(): number {
return this.shaderData.getFloat(PBRMaterial._roughnessProp);
Expand All @@ -50,14 +51,30 @@ export class PBRMaterial extends PBRBaseMaterial {
}
}

/**
* Index of refraction of the material, default 1.5 .
* @remarks It influence the F0 of dielectric materials.
*/
get ior(): number {
return this.shaderData.getFloat(PBRMaterial._iorProp);
}

set ior(value: number) {
this.shaderData.setFloat(PBRMaterial._iorProp, value);
}

/**
* Create a pbr metallic-roughness workflow material instance.
* @param engine - Engine to which the material belongs
*/
constructor(engine: Engine) {
super(engine, Shader.find("pbr"));
this.shaderData.setFloat(PBRMaterial._metallicProp, 1.0);
this.shaderData.setFloat(PBRMaterial._roughnessProp, 1.0);

const shaderData = this.shaderData;

shaderData.setFloat(PBRMaterial._metallicProp, 1);
shaderData.setFloat(PBRMaterial._roughnessProp, 1);
shaderData.setFloat(PBRMaterial._iorProp, 1.5);
}

/**
Expand Down
12 changes: 5 additions & 7 deletions packages/core/src/shaderlib/begin_normal_vert.glsl
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#ifndef OMIT_NORMAL
#ifdef O3_HAS_NORMAL
vec3 normal = vec3( NORMAL );
#endif

vec3 normal = vec3( NORMAL );

#if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE )

#ifdef O3_HAS_TANGENT
vec4 tangent = vec4( TANGENT );

#endif

#endif
#endif
4 changes: 4 additions & 0 deletions packages/core/src/shaderlib/common.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#define saturate( a ) clamp( a, 0.0, 1.0 )
#define whiteCompliment(a) ( 1.0 - saturate( a ) )

float pow2(float x ) {
return x * x;
}

vec4 RGBMToLinear(vec4 value, float maxRange ) {
return vec4( value.rgb * value.a * maxRange, 1.0 );
}
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/shaderlib/mobile_blinnphong_frag.glsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
vec3 N = getNormal();
vec3 N = getNormal(
#ifdef O3_NORMAL_TEXTURE
u_normalTexture,
u_normalIntensity
#endif
);
vec3 lightDiffuse = vec3( 0.0, 0.0, 0.0 );
vec3 lightSpecular = vec3( 0.0, 0.0, 0.0 );

Expand Down
44 changes: 24 additions & 20 deletions packages/core/src/shaderlib/normal_get.glsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
vec3 getNormal()
vec3 getNormal(){
vec3 normal = vec3(0, 0, 1);

#ifdef O3_HAS_NORMAL
normal = normalize(v_normal);
#elif defined(HAS_DERIVATIVES)
vec3 pos_dx = dFdx(v_pos);
vec3 pos_dy = dFdy(v_pos);
normal = normalize( cross(pos_dx, pos_dy) );
#endif

normal *= float( gl_FrontFacing ) * 2.0 - 1.0;
return normal;
}

vec3 getNormal(sampler2D normalTexture, float normalIntensity)
{
#ifdef O3_NORMAL_TEXTURE
#ifndef O3_HAS_TANGENT

#if defined(O3_HAS_NORMAL) && defined(O3_HAS_TANGENT) && defined( O3_NORMAL_TEXTURE )
mat3 tbn = v_TBN;
#else
#ifdef HAS_DERIVATIVES
vec3 pos_dx = dFdx(v_pos);
vec3 pos_dy = dFdy(v_pos);
Expand All @@ -24,24 +41,11 @@ vec3 getNormal()
#endif
mat3 tbn = mat3(vec3(0.0), vec3(0.0), ng);
#endif
#else
mat3 tbn = v_TBN;
#endif
vec3 n = texture2D(u_normalTexture, v_uv ).rgb;
n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_normalIntensity, u_normalIntensity, 1.0)));
#else
#ifdef O3_HAS_NORMAL
vec3 n = normalize(v_normal);
#elif defined(HAS_DERIVATIVES)
vec3 pos_dx = dFdx(v_pos);
vec3 pos_dy = dFdy(v_pos);
vec3 n = normalize( cross(pos_dx, pos_dy) );
#else
vec3 n= vec3(0.0,0.0,1.0);
#endif
#endif

n *= float( gl_FrontFacing ) * 2.0 - 1.0;
vec3 normal = texture2D(normalTexture, v_uv ).rgb;
normal = normalize(tbn * ((2.0 * normal - 1.0) * vec3(normalIntensity, normalIntensity, 1.0)));
normal *= float( gl_FrontFacing ) * 2.0 - 1.0;

return n;
return normal;
}
19 changes: 7 additions & 12 deletions packages/core/src/shaderlib/normal_share.glsl
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
#ifdef O3_HAS_NORMAL

#if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE )

varying mat3 v_TBN;

#else

varying vec3 v_normal;

#ifndef OMIT_NORMAL
#ifdef O3_HAS_NORMAL
varying vec3 v_normal;
#if defined( O3_HAS_TANGENT ) && defined( O3_NORMAL_TEXTURE )
varying mat3 v_TBN;
#endif
#endif

#endif
#endif
Loading