diff --git a/packages/core/src/Engine.ts b/packages/core/src/Engine.ts index 8f8bc186c7..73fee9ba0f 100644 --- a/packages/core/src/Engine.ts +++ b/packages/core/src/Engine.ts @@ -16,6 +16,7 @@ import { Shader } from "./shader/Shader"; import { ShaderPool } from "./shader/ShaderPool"; import { ShaderProgramPool } from "./shader/ShaderProgramPool"; import { RenderState } from "./shader/state/RenderState"; +import { Texture2D, TextureCubeFace, TextureCubeMap, TextureFormat } from "./texture"; /** TODO: delete */ const engineFeatureManager = new FeatureManager(); @@ -31,6 +32,10 @@ export class Engine extends EventDispatcher { _renderElementPool: ClassPool = new ClassPool(RenderElement); _renderContext: RenderContext = new RenderContext(); + /* @internal */ + _whiteTexture2D: Texture2D; + /* @internal */ + _whiteTextureCube: TextureCubeMap; /* @internal */ _renderCount: number = 0; /* @internal */ @@ -142,6 +147,22 @@ export class Engine extends EventDispatcher { // @todo delete engineFeatureManager.addObject(this); this._sceneManager.activeScene = new Scene(this, "DefaultScene"); + + const whitePixel = new Uint8Array([255, 255, 255, 255]); + + const whiteTextrue2D = new Texture2D(this, 1, 1, TextureFormat.R8G8B8A8, false); + whiteTextrue2D.setPixelBuffer(whitePixel); + + const whiteTextrueCube = new TextureCubeMap(this, 1, TextureFormat.R8G8B8A8, false); + whiteTextrueCube.setPixelBuffer(TextureCubeFace.PositiveX, whitePixel); + whiteTextrueCube.setPixelBuffer(TextureCubeFace.NegativeX, whitePixel); + whiteTextrueCube.setPixelBuffer(TextureCubeFace.PositiveY, whitePixel); + whiteTextrueCube.setPixelBuffer(TextureCubeFace.NegativeY, whitePixel); + whiteTextrueCube.setPixelBuffer(TextureCubeFace.PositiveZ, whitePixel); + whiteTextrueCube.setPixelBuffer(TextureCubeFace.NegativeZ, whitePixel); + + this._whiteTexture2D = whiteTextrue2D; + this._whiteTextureCube = whiteTextrueCube; } /** diff --git a/packages/core/src/shader/ShaderProgram.ts b/packages/core/src/shader/ShaderProgram.ts index d3880534f1..9794029463 100644 --- a/packages/core/src/shader/ShaderProgram.ts +++ b/packages/core/src/shader/ShaderProgram.ts @@ -5,6 +5,7 @@ import { Engine } from "../Engine"; import { Material } from "../material/Material"; import { Renderer } from "../Renderer"; import { IHardwareRenderer } from "../renderingHardwareInterface/IHardwareRenderer"; +import { Texture } from "../texture"; import { ShaderDataGroup } from "./enums/ShaderDataGroup"; import { Shader } from "./Shader"; import { ShaderData } from "./ShaderData"; @@ -124,7 +125,11 @@ export class ShaderProgram { for (let i = 0, n = textureUniforms.length; i < n; i++) { const uniform = textureUniforms[i]; const texture = properties[uniform.propertyId]; - texture != null && uniform.applyFunc(uniform, texture); + if (texture) { + uniform.applyFunc(uniform, texture); + } else { + uniform.applyFunc(uniform, uniform.textureDefault); + } } } } @@ -383,20 +388,28 @@ export class ShaderProgram { break; case gl.SAMPLER_2D: case gl.SAMPLER_CUBE: + const defaultTexture = type === gl.SAMPLER_2D ? this._engine._whiteTexture2D : this._engine._whiteTextureCube; + isTexture = true; if (isArray) { + const textureDefaults = new Array(size); const textureIndices = new Int32Array(size); const glTextureIndices = new Array(size); + for (let i = 0; i < size; i++) { + textureDefaults[i] = defaultTexture; textureIndices[i] = this._activeTextureUint; glTextureIndices[i] = gl.TEXTURE0 + this._activeTextureUint++; } + shaderUniform.textureDefault = textureDefaults; shaderUniform.textureIndex = glTextureIndices; shaderUniform.applyFunc = shaderUniform.uploadTextureArray; this.bind(); gl.uniform1iv(location, textureIndices); } else { const textureIndex = gl.TEXTURE0 + this._activeTextureUint; + + shaderUniform.textureDefault = defaultTexture; shaderUniform.textureIndex = textureIndex; shaderUniform.applyFunc = shaderUniform.uploadTexture; this.bind(); diff --git a/packages/core/src/shader/ShaderUniform.ts b/packages/core/src/shader/ShaderUniform.ts index d5dc984f93..867f1c606f 100644 --- a/packages/core/src/shader/ShaderUniform.ts +++ b/packages/core/src/shader/ShaderUniform.ts @@ -12,9 +12,10 @@ export class ShaderUniform { name: string; propertyId: number; location: WebGLUniformLocation; - textureIndex: GLenum | GLenum[]; applyFunc: (shaderUniform: ShaderUniform, value: ShaderPropertyValueType) => void; cacheValue: number | Vector2 | Vector3 | Vector4; + textureIndex: GLenum | GLenum[]; + textureDefault: Texture | Texture[]; private _rhi: IHardwareRenderer; private _gl: WebGLRenderingContext;