|
@@ -1,6 +1,19 @@
|
|
|
module BABYLON {
|
|
|
+ /**
|
|
|
+ * "Static Class" containing the most commonly used helper while dealing with material for
|
|
|
+ * rendering purpose.
|
|
|
+ *
|
|
|
+ * It contains the basic tools to help defining defines, binding uniform for the common part of the materials.
|
|
|
+ *
|
|
|
+ * This works by convention in BabylonJS but is meant to be use only with shader following the in place naming rules and conventions.
|
|
|
+ */
|
|
|
export class MaterialHelper {
|
|
|
|
|
|
+ /**
|
|
|
+ * Bind the current view position to an effect.
|
|
|
+ * @param effect The effect to be bound
|
|
|
+ * @param scene The scene the eyes position is used from
|
|
|
+ */
|
|
|
public static BindEyePosition(effect: Effect, scene: Scene): void {
|
|
|
if (scene._forcedViewPosition) {
|
|
|
effect.setVector3("vEyePosition", scene._forcedViewPosition);
|
|
@@ -9,6 +22,13 @@ module BABYLON {
|
|
|
effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera!.globalPosition);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Helps preparing the defines values about the UVs in used in the effect.
|
|
|
+ * UVs are shared as much as we can accross chanels in the shaders.
|
|
|
+ * @param texture The texture we are preparing the UVs for
|
|
|
+ * @param defines The defines to update
|
|
|
+ * @param key The chanel key "diffuse", "specular"... used in the shader
|
|
|
+ */
|
|
|
public static PrepareDefinesForMergedUV(texture: BaseTexture, defines: any, key: string): void {
|
|
|
defines._needUVs = true;
|
|
|
defines[key] = true;
|
|
@@ -24,6 +44,12 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Binds a texture matrix value to its corrsponding uniform
|
|
|
+ * @param texture The texture to bind the matrix for
|
|
|
+ * @param uniformBuffer The uniform buffer receivin the data
|
|
|
+ * @param key The chanel key "diffuse", "specular"... used in the shader
|
|
|
+ */
|
|
|
public static BindTextureMatrix(texture: BaseTexture, uniformBuffer: UniformBuffer, key: string): void {
|
|
|
var matrix = texture.getTextureMatrix();
|
|
|
|
|
@@ -58,7 +84,6 @@ module BABYLON {
|
|
|
* @param engine defines the current engine
|
|
|
* @param defines specifies the list of active defines
|
|
|
* @param useInstances defines if instances have to be turned on
|
|
|
- * @param alphaTest defines if alpha testing has to be turned on
|
|
|
*/
|
|
|
public static PrepareDefinesForFrameBoundValues(scene: Scene, engine: Engine, defines: any, useInstances: boolean): void {
|
|
|
var changed = false;
|
|
@@ -83,6 +108,15 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Prepares the defines used in the shader depending on the attributes data available in the mesh
|
|
|
+ * @param mesh The mesh containing the geometry data we will draw
|
|
|
+ * @param defines The defines to update
|
|
|
+ * @param useVertexColor Precise whether vertex colors should be used or not (override mesh info)
|
|
|
+ * @param useBones Precise whether bones should be used or not (override mesh info)
|
|
|
+ * @param useMorphTargets Precise whether morph targets should be used or not (override mesh info)
|
|
|
+ * @param useVertexAlpha Precise whether vertex alpha should be used or not (override mesh info)
|
|
|
+ */
|
|
|
public static PrepareDefinesForAttributes(mesh: AbstractMesh, defines: any, useVertexColor: boolean, useBones: boolean, useMorphTargets = false, useVertexAlpha = true): boolean {
|
|
|
if (!defines._areAttributesDirty && defines._needNormals === defines._normals && defines._needUVs === defines._uvs) {
|
|
|
return false;
|
|
@@ -139,6 +173,16 @@ module BABYLON {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Prepares the defines related to the light information passed in parameter
|
|
|
+ * @param scene The scene we are intending to draw
|
|
|
+ * @param mesh The mesh the effect is compiling for
|
|
|
+ * @param defines The defines to update
|
|
|
+ * @param specularSupported Specifies whether specular is supported or not (override lights data)
|
|
|
+ * @param maxSimultaneousLights Specfies how manuy lights can be added to the effect at max
|
|
|
+ * @param disableLighting Specifies whether the lighting is disabled (override scene and light)
|
|
|
+ * @returns true if normals will be required for the rest of the effect
|
|
|
+ */
|
|
|
public static PrepareDefinesForLights(scene: Scene, mesh: AbstractMesh, defines: any, specularSupported: boolean, maxSimultaneousLights = 4, disableLighting = false): boolean {
|
|
|
if (!defines._areLightsDirty) {
|
|
|
return defines._needNormals;
|
|
@@ -247,6 +291,14 @@ module BABYLON {
|
|
|
return needNormals;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Prepares the uniforms and samplers list to be used in the effect. This can automatically remove from the list uniforms
|
|
|
+ * that won t be acctive due to defines being turned off.
|
|
|
+ * @param uniformsListOrOptions The uniform names to prepare or an EffectCreationOptions containing the liist and extra information
|
|
|
+ * @param samplersList The samplers list
|
|
|
+ * @param defines The defines helping in the list generation
|
|
|
+ * @param maxSimultaneousLights The maximum number of simultanous light allowed in the effect
|
|
|
+ */
|
|
|
public static PrepareUniformsAndSamplersList(uniformsListOrOptions: string[] | EffectCreationOptions, samplersList?: string[], defines?: any, maxSimultaneousLights = 4): void {
|
|
|
let uniformsList: string[];
|
|
|
let uniformBuffersList: Nullable<string[]> = null;
|
|
@@ -299,6 +351,14 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * This helps decreasing rank by rank the shadow quality (0 being the highest rank and quality)
|
|
|
+ * @param defines The defines to update while falling back
|
|
|
+ * @param fallbacks The authorized effect fallbacks
|
|
|
+ * @param maxSimultaneousLights The maximum number of lights allowed
|
|
|
+ * @param rank the current rank of the Effect
|
|
|
+ * @returns The newly affected rank
|
|
|
+ */
|
|
|
public static HandleFallbacksForShadows(defines: any, fallbacks: EffectFallbacks, maxSimultaneousLights = 4, rank = 0): number {
|
|
|
let lightFallbackRank = 0;
|
|
|
for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
|
|
@@ -328,6 +388,12 @@ module BABYLON {
|
|
|
return lightFallbackRank++;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Prepares the list of attributes required for morph targets according to the effect defines.
|
|
|
+ * @param attribs The current list of supported attribs
|
|
|
+ * @param mesh The mesh to prepare the morph targets attributes for
|
|
|
+ * @param defines The current Defines of the effect
|
|
|
+ */
|
|
|
public static PrepareAttributesForMorphTargets(attribs: string[], mesh: AbstractMesh, defines: any): void {
|
|
|
var influencers = defines["NUM_MORPH_INFLUENCERS"];
|
|
|
|
|
@@ -354,6 +420,13 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Prepares the list of attributes required for bones according to the effect defines.
|
|
|
+ * @param attribs The current list of supported attribs
|
|
|
+ * @param mesh The mesh to prepare the bones attributes for
|
|
|
+ * @param defines The current Defines of the effect
|
|
|
+ * @param fallbacks The current efffect fallback strategy
|
|
|
+ */
|
|
|
public static PrepareAttributesForBones(attribs: string[], mesh: AbstractMesh, defines: any, fallbacks: EffectFallbacks): void {
|
|
|
if (defines["NUM_BONE_INFLUENCERS"] > 0) {
|
|
|
fallbacks.addCPUSkinningFallback(0, mesh);
|
|
@@ -367,6 +440,11 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Prepares the list of attributes required for instances according to the effect defines.
|
|
|
+ * @param attribs The current list of supported attribs
|
|
|
+ * @param defines The current Defines of the effect
|
|
|
+ */
|
|
|
public static PrepareAttributesForInstances(attribs: string[], defines: any): void {
|
|
|
if (defines["INSTANCES"]) {
|
|
|
attribs.push("world0");
|
|
@@ -376,7 +454,14 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Bindings
|
|
|
+ /**
|
|
|
+ * Binds the light shadow information to the effect for the given mesh.
|
|
|
+ * @param light The light containing the generator
|
|
|
+ * @param scene The scene the lights belongs to
|
|
|
+ * @param mesh The mesh we are binding the information to render
|
|
|
+ * @param lightIndex The light index in the effect used to render the mesh
|
|
|
+ * @param effect The effect we are binding the data to
|
|
|
+ */
|
|
|
public static BindLightShadow(light: Light, scene: Scene, mesh: AbstractMesh, lightIndex: string, effect: Effect): void {
|
|
|
if (light.shadowEnabled && mesh.receiveShadows) {
|
|
|
var shadowGenerator = light.getShadowGenerator();
|
|
@@ -386,11 +471,26 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Binds the light information to the effect.
|
|
|
+ * @param light The light containing the generator
|
|
|
+ * @param effect The effect we are binding the data to
|
|
|
+ * @param lightIndex The light index in the effect used to render
|
|
|
+ */
|
|
|
public static BindLightProperties(light: Light, effect: Effect, lightIndex: number): void {
|
|
|
light.transferToEffect(effect, lightIndex + "");
|
|
|
}
|
|
|
|
|
|
- public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: any, maxSimultaneousLights = 4, usePhysicalLightFalloff = false) {
|
|
|
+ /**
|
|
|
+ * Binds the lights information from the scene to the effect for the given mesh.
|
|
|
+ * @param scene The scene the lights belongs to
|
|
|
+ * @param mesh The mesh we are binding the information to render
|
|
|
+ * @param effect The effect we are binding the data to
|
|
|
+ * @param defines The generated defines for the effect
|
|
|
+ * @param maxSimultaneousLights The maximum number of light that can be bound to the effect
|
|
|
+ * @param usePhysicalLightFalloff Specifies whether the light falloff is defined physically or not
|
|
|
+ */
|
|
|
+ public static BindLights(scene: Scene, mesh: AbstractMesh, effect: Effect, defines: any, maxSimultaneousLights = 4, usePhysicalLightFalloff = false): void {
|
|
|
let len = Math.min(mesh._lightSources.length, maxSimultaneousLights);
|
|
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
@@ -418,6 +518,12 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Binds the fog information from the scene to the effect for the given mesh.
|
|
|
+ * @param scene The scene the lights belongs to
|
|
|
+ * @param mesh The mesh we are binding the information to render
|
|
|
+ * @param effect The effect we are binding the data to
|
|
|
+ */
|
|
|
public static BindFogParameters(scene: Scene, mesh: AbstractMesh, effect: Effect): void {
|
|
|
if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== Scene.FOGMODE_NONE) {
|
|
|
effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
|
|
@@ -425,6 +531,11 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Binds the bones information from the mesh to the effect.
|
|
|
+ * @param mesh The mesh we are binding the information to render
|
|
|
+ * @param effect The effect we are binding the data to
|
|
|
+ */
|
|
|
public static BindBonesParameters(mesh?: AbstractMesh, effect?: Effect): void {
|
|
|
if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
|
|
|
var matrices = mesh.skeleton.getTransformMatrices(mesh);
|
|
@@ -435,6 +546,11 @@ module BABYLON {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Binds the morph targets information from the mesh to the effect.
|
|
|
+ * @param mesh The mesh we are binding the information to render
|
|
|
+ * @param effect The effect we are binding the data to
|
|
|
+ */
|
|
|
public static BindMorphTargetParameters(abstractMesh: AbstractMesh, effect: Effect): void {
|
|
|
let manager = (<Mesh>abstractMesh).morphTargetManager;
|
|
|
if (!abstractMesh || !manager) {
|
|
@@ -444,12 +560,23 @@ module BABYLON {
|
|
|
effect.setFloatArray("morphTargetInfluences", manager.influences);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Binds the logarithmic depth information from the scene to the effect for the given defines.
|
|
|
+ * @param defines The generated defines used in the effect
|
|
|
+ * @param effect The effect we are binding the data to
|
|
|
+ * @param scene The scene we are willing to render with logarithmic scale for
|
|
|
+ */
|
|
|
public static BindLogDepth(defines: any, effect: Effect, scene: Scene): void {
|
|
|
if (defines["LOGARITHMICDEPTH"]) {
|
|
|
effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log((<Camera>scene.activeCamera).maxZ + 1.0) / Math.LN2));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Binds the clip plane information from the scene to the effect.
|
|
|
+ * @param scene The scene the clip plane information are extracted from
|
|
|
+ * @param effect The effect we are binding the data to
|
|
|
+ */
|
|
|
public static BindClipPlane(effect: Effect, scene: Scene): void {
|
|
|
if (scene.clipPlane) {
|
|
|
var clipPlane = scene.clipPlane;
|