Skip to content

Commit

Permalink
refactor material instance
Browse files Browse the repository at this point in the history
  • Loading branch information
zxg0622 committed Dec 20, 2019
1 parent 25636a6 commit ae645ec
Show file tree
Hide file tree
Showing 29 changed files with 1,323 additions and 350 deletions.
4 changes: 2 additions & 2 deletions cocos/core/3d/framework/batched-skinning-model-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class SkinningModelUnit {
if (!comp) { return; }
this.mesh = comp.mesh;
this.skeleton = comp.skeleton;
this.material = comp.getSharedMaterial(0);
this.material = comp.getMaterial(0);
}
get copyFrom () {
return null;
Expand Down Expand Up @@ -164,7 +164,7 @@ export class BatchedSkinningModelComponent extends SkinningModelComponent {

public cookMaterials () {
if (!this._batchMaterial) {
this._batchMaterial = this.getSharedMaterial(0);
this._batchMaterial = this.getMaterial(0);
}
const mat = this.getMaterial(0);
if (!mat || !this._batchMaterial || !this._batchMaterial.effectAsset) {
Expand Down
8 changes: 4 additions & 4 deletions cocos/core/3d/framework/model-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export class ModelComponent extends RenderableComponent {
}
if (this._model) {
this._model.isDynamicBatching = enable;
this._model.onPipelineChange(); // update material
this._model.onGlobalPipelineStateChanged(); // update material
for (let i = 0; i < this._model.subModels.length; ++i) {
const subModel = this._model.subModels[i];
for (let p = 0; p < subModel.passes.length; ++p) {
Expand Down Expand Up @@ -268,7 +268,7 @@ export class ModelComponent extends RenderableComponent {
this._model.isDynamicBatching = this._enableDynamicBatching; // should pass this in before create PSO
const meshCount = this._mesh ? this._mesh.subMeshCount : 0;
for (let i = 0; i < meshCount; ++i) {
const material = this.getSharedMaterial(i);
const material = this.getRenderMaterial(i);
const renderingMesh = this._mesh.renderingMesh;
if (renderingMesh) {
const subMeshData = renderingMesh.getSubmesh(i);
Expand All @@ -280,7 +280,7 @@ export class ModelComponent extends RenderableComponent {
}

protected _onMaterialModified (idx: number, material: Material | null) {
if (this._model == null) {
if (this._model == null || !this._model.inited) {
return;
}
this._onRebuildPSO(idx, material || this._getBuiltinMaterial());
Expand All @@ -298,7 +298,7 @@ export class ModelComponent extends RenderableComponent {
}

protected _onRebuildPSO (idx: number, material: Material) {
if (this._model) {
if (this._model && this._model.inited) {
this._model.setSubModelMaterial(idx, material);
}
}
Expand Down
122 changes: 84 additions & 38 deletions cocos/core/3d/framework/renderable-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import { Material } from '../../assets/material';
import { Component } from '../../components/component';
import { _decorator } from '../../data/index';
import { MaterialInstance } from '../../renderer/core/material-instance';
import { Model } from '../../renderer/scene/model';
import { Layers } from '../../scene-graph/layers';
import { IMaterial } from '../../utils/material-interface';
const { ccclass, property } = _decorator;

@ccclass('cc.RenderableComponent')
Expand All @@ -18,6 +20,8 @@ export class RenderableComponent extends Component {
})
protected _materials: Array<Material | null> = [];

protected _materialInstances: Array<MaterialInstance | null> = [];

@property
protected _visFlags = Layers.Enum.NONE;

Expand All @@ -41,17 +45,49 @@ export class RenderableComponent extends Component {
set sharedMaterials (val) {
for (let i = 0; i < val.length; i++) {
if (val[i] !== this._materials[i]) {
this.setMaterial(val[i], i);
this.setMaterial(i, val[i]);
}
}
if (val.length < this._materials.length) {
for (let i = val.length; i < this._materials.length; i++) {
this.setMaterial(null, i);
this.setMaterial(i, null);
}
this._materials.splice(val.length);
}
}

get sharedMaterial () {
return this.getMaterial(0);
}

/**
* 获取指定的sharedMaterial
* @param idx 材质序号
*/
public getMaterial (idx: number): Material | null {
if (idx < 0 || idx >= this._materials.length) {
return null;
}
return this._materials[idx];
}

/**
* 设置指定的sharedMaterial,如果对应位置有材质实例则会创建一个对应的材质实例
* @param index 材质序号
* @param material 材质对象
*/
public setMaterial (index: number, material: Material | null) {
this._materials[index] = material;
if (this._materialInstances[index]) {
if (this._materialInstances[index]!.parent !== material) {
this.getMaterialInstance(index);
this._onMaterialModified(index, material);
}
} else {
this._onMaterialModified(index, material);
}
}

/**
* @en The material of the model
* @zh 模型材质。
Expand All @@ -64,7 +100,7 @@ export class RenderableComponent extends Component {
})
get materials () {
for (let i = 0; i < this._materials.length; i++) {
this._materials[i] = this.getMaterial(i)!;
this._materialInstances[i] = this.getMaterialInstance(i) as MaterialInstance;
}
return this._materials;
}
Expand All @@ -75,47 +111,64 @@ export class RenderableComponent extends Component {
this._materials = this._materials.concat(new Array(dLen).fill(null));
} else if (dLen < 0) {
for (let i = -dLen; i < this._materials.length; ++i) {
this.setMaterial(null, i);
this.setMaterialInstance(i, null);
}
this._materials = this._materials.splice(-dLen);
}
}

get material () {
return this.getMaterialInstance(0);
}

set material (val) {
if (this._materials.length === 1 && this._materials[0] === val) {
return;
}
this.setMaterialInstance(0, val);
}

/**
* @en Returns the material corresponding to the sequence number
* @zh 返回相对应序号的材质
* @en Returns the material instance corresponding to the sequence number
* @zh 获取相对应序号的材质实例
* @param {Number} idx - Look for the material list number
*/
public getMaterial (idx: number, inEditor: boolean = CC_EDITOR, autoUpdate: boolean = false): Material | null {
public getMaterialInstance (idx: number): IMaterial | null {
const mat = this._materials[idx];
if (!mat) { return null; }
const instantiated = Material.getInstantiatedMaterial(mat, this, inEditor);
if (instantiated !== this._materials[idx]) {
this.setMaterial(instantiated, idx, autoUpdate || !inEditor);
}
return this._materials[idx];
}

public getSharedMaterial (idx: number): Material | null {
if (idx < 0 || idx >= this._materials.length) {
if (!mat) {
return null;
}
return this._materials[idx];
}

get material () {
return this.getMaterial(0);
if (this._materialInstances[idx] == null) {
const instantiated = new MaterialInstance(this._materials[idx]!, this);
this.setMaterialInstance(idx, instantiated);
}
return this._materialInstances[idx];
}

set material (val) {
if (this._materials.length === 1 && this._materials[0] === val) {
return;
/**
* 设置对应序号的材质实例
* @param index 材质序号
* @param matInst 材质实例
*/
public setMaterialInstance (index: number, matInst: IMaterial | null) {
if (matInst && matInst.parent) {
if (matInst !== this._materialInstances[index]) {
this._materialInstances[index] = matInst as MaterialInstance;
this._onMaterialModified(index, matInst);
}
} else {
if (matInst !== this._materials[index]) {
this.setMaterial(index, matInst as Material);
}
}
this.setMaterial(val, 0);
}

get sharedMaterial () {
return this.getSharedMaterial(0);
/**
* 获取指定位置可供渲染的材质,如果有材质实例则使用材质实例,如果没有则使用材质资源
* @param index 材质序号
*/
public getRenderMaterial (index: number): IMaterial | null {
return this._materialInstances[index] || this._materials[index];
}

@property({ visible: false })
Expand All @@ -128,24 +181,17 @@ export class RenderableComponent extends Component {
this._onVisiblityChange(val);
}

public setMaterial (material: Material | null, index: number, notify: boolean = true) {
this._materials[index] = material;
if (notify) {
this._onMaterialModified(index, material);
}
}

public _collectModels (): Model[] {
return this._models;
}

protected _attachToScene() {
protected _attachToScene () {
}

protected _detachFromScene() {
protected _detachFromScene () {
}

protected _onMaterialModified (index: number, material: Material | null) {
protected _onMaterialModified (index: number, material: IMaterial | null) {

}

Expand Down
Loading

0 comments on commit ae645ec

Please sign in to comment.