diff --git a/samples/sky/Sample_AtmosphericSky.ts b/samples/sky/Sample_AtmosphericSky.ts index a8a2c165..eb1e44d9 100644 --- a/samples/sky/Sample_AtmosphericSky.ts +++ b/samples/sky/Sample_AtmosphericSky.ts @@ -1,43 +1,19 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, Texture, AtmosphericScatteringSky, BoxGeometry, LitMaterial, MeshRenderer, Object3D } from "@orillusion/core"; import { GUIUtil } from "@samples/utils/GUIUtil"; +import { createExampleScene } from "@samples/utils/ExampleScene"; +import { AtmosphericComponent, Engine3D, Scene3D } from "@orillusion/core"; // sample of AtmosphericSky class Sample_AtmosphericSky { - private _scene: Scene3D; - async run() { // init engine await Engine3D.init({}); - // init scene - this._scene = new Scene3D(); - // add atmospheric sky - let component = this._scene.addComponent(AtmosphericComponent); - - // init camera3D - let mainCamera = CameraUtil.createCamera3D(null, this._scene); - mainCamera.perspective(60, Engine3D.aspect, 1, 2000.0); - - // camera controller - mainCamera.object3D.addComponent(HoverCameraController).setCamera(45, -10, 10); - - // create a basic cube - let cubeObj = new Object3D(); - let mr = cubeObj.addComponent(MeshRenderer); - mr.geometry = new BoxGeometry(); - let mat = new LitMaterial(); - mr.material = mat; - this._scene.addChild(cubeObj); - - // init view3D - let view = new View3D(); - view.scene = this._scene; - view.camera = mainCamera; - + let scene: Scene3D = createExampleScene().scene; // start renderer - Engine3D.startRenderView(view); - + Engine3D.startRenderView(scene.view); + // add atmospheric sky + let component = scene.getComponent(AtmosphericComponent); // gui GUIHelp.init(); GUIUtil.renderAtomosphericSky(component); diff --git a/samples/sky/Sample_BitmapCubeSky.ts b/samples/sky/Sample_BitmapCubeSky.ts index 21167164..ab8d5eb4 100644 --- a/samples/sky/Sample_BitmapCubeSky.ts +++ b/samples/sky/Sample_BitmapCubeSky.ts @@ -1,40 +1,14 @@ -import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Scene3D, Engine3D, CameraUtil, HoverCameraController, View3D, Texture, SkyRenderer, Object3D, BoxGeometry, LitMaterial, MeshRenderer } from "@orillusion/core"; +import { createExampleScene } from "@samples/utils/ExampleScene"; +import { Engine3D, Scene3D, SkyRenderer, Object3DUtil } from "@orillusion/core"; // sample to replace sky map. (witch contains 6 faces) class Sample_BitmapCubeSky { - private _scene: Scene3D; async run() { // init engine await Engine3D.init({}); - // init scene - this._scene = new Scene3D(); - - // init camera3D - let mainCamera = CameraUtil.createCamera3D(null, this._scene); - mainCamera.perspective(60, Engine3D.aspect, 1, 2000.0); - - // camera controller - let hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController); - hoverCameraController.setCamera(45, -10, 10); - - // create a basic cube - let cubeObj = new Object3D(); - let mr = cubeObj.addComponent(MeshRenderer); - mr.geometry = new BoxGeometry(); - let mat = new LitMaterial(); - mr.material = mat; - this._scene.addChild(cubeObj); - - // init view3D - let view = new View3D(); - view.scene = this._scene; - view.camera = mainCamera; - - // start renderer - Engine3D.startRenderView(view); - + let scene: Scene3D = createExampleScene().scene; + let sky = scene.getOrAddComponent(SkyRenderer); // load sky texture (nx/px/py/ny/nz/pz), a total of 6 images let urls: string[] = []; urls.push('textures/cubemap/skybox_nx.png'); @@ -44,11 +18,14 @@ class Sample_BitmapCubeSky { urls.push('textures/cubemap/skybox_nz.png'); urls.push('textures/cubemap/skybox_pz.png'); - let sky = this._scene.addComponent(SkyRenderer) sky.map = await Engine3D.res.loadTextureCubeMaps(urls); - this._scene.envMap = sky.map - } + // create a basic cube + scene.addChild(Object3DUtil.GetSingleCube(10, 10, 10, 0.6, 0.6, 0.6)); + // start renderer + Engine3D.startRenderView(scene.view); + + } } new Sample_BitmapCubeSky().run(); \ No newline at end of file diff --git a/samples/sky/Sample_BitmapCubeStdSky.ts b/samples/sky/Sample_BitmapCubeStdSky.ts index 3e255e3a..3dba452e 100644 --- a/samples/sky/Sample_BitmapCubeStdSky.ts +++ b/samples/sky/Sample_BitmapCubeStdSky.ts @@ -1,48 +1,22 @@ -import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, Texture, SkyRenderer, BoxGeometry, LitMaterial, MeshRenderer, Object3D } from "@orillusion/core"; +import { createExampleScene } from "@samples/utils/ExampleScene"; +import { Engine3D, Scene3D, SkyRenderer, Object3DUtil } from "@orillusion/core"; // sample to replace standard sky map class Sample_BitmapCubeStdSky { - private _scene: Scene3D; async run() { // init engine await Engine3D.init({}); - // init scene - this._scene = new Scene3D(); - - // init camera3D - let mainCamera = CameraUtil.createCamera3D(null, this._scene); - mainCamera.perspective(60, Engine3D.aspect, 1, 2000.0); - - // camera controller - let hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController); - hoverCameraController.setCamera(45, -10, 10); + let scene: Scene3D = createExampleScene().scene; + let sky = scene.getOrAddComponent(SkyRenderer); + sky.map = await Engine3D.res.loadTextureCubeStd('sky/StandardCubeMap-2.jpg'); // create a basic cube - let cubeObj = new Object3D(); - let mr = cubeObj.addComponent(MeshRenderer); - mr.geometry = new BoxGeometry(); - let mat = new LitMaterial(); - mr.material = mat; - this._scene.addChild(cubeObj); - - // init view3D - let view = new View3D(); - view.scene = this._scene; - view.camera = mainCamera; + scene.addChild(Object3DUtil.GetSingleCube(10, 10, 10, 0.6, 0.6, 0.6)); // start renderer - Engine3D.startRenderView(view); - - // load standard sky texture - let url = 'sky/StandardCubeMap-2.jpg'; - - let sky = this._scene.addComponent(SkyRenderer) - sky.map = await Engine3D.res.loadTextureCubeStd(url); - this._scene.envMap = sky.map + Engine3D.startRenderView(scene.view); } - } new Sample_BitmapCubeStdSky().run(); \ No newline at end of file diff --git a/samples/sky/Sample_HDRSky.ts b/samples/sky/Sample_HDRSky.ts index 28f0d9c0..5ec13e4a 100644 --- a/samples/sky/Sample_HDRSky.ts +++ b/samples/sky/Sample_HDRSky.ts @@ -1,48 +1,24 @@ -import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, Texture, SkyRenderer, BoxGeometry, LitMaterial, MeshRenderer, Object3D } from "@orillusion/core"; +import { createExampleScene } from "@samples/utils/ExampleScene"; +import { Engine3D, Scene3D, SkyRenderer, Object3DUtil } from "@orillusion/core"; // sample to replace hdr sky map class Sample_HDRSky { - private _scene: Scene3D; - private _externalTexture: Texture; - private _originTexture: Texture; - private _useExternal: boolean = false; async run() { // init engine await Engine3D.init({}); - // init scene - this._scene = new Scene3D(); - // load sky texture - let sky = this._scene.addComponent(SkyRenderer) + let scene: Scene3D = createExampleScene().scene; + let sky = scene.getOrAddComponent(SkyRenderer); sky.map = await Engine3D.res.loadHDRTextureCube('/hdri/sunset.hdr'); - this._scene.envMap = sky.map - - // init camera3D - let mainCamera = CameraUtil.createCamera3D(null, this._scene); - mainCamera.perspective(60, Engine3D.aspect, 1, 2000.0); // create a basic cube - let cubeObj = new Object3D(); - let mr = cubeObj.addComponent(MeshRenderer); - mr.geometry = new BoxGeometry(); - let mat = new LitMaterial(); - mr.material = mat; - this._scene.addChild(cubeObj); - - // camera controller - let hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController); - hoverCameraController.setCamera(45, -10, 10); - - // init view3D - let view = new View3D(); - view.scene = this._scene; - view.camera = mainCamera; + scene.addChild(Object3DUtil.GetSingleCube(10, 10, 10, 0.6, 0.6, 0.6)); // start renderer - Engine3D.startRenderView(view); + Engine3D.startRenderView(scene.view); } } + new Sample_HDRSky().run(); \ No newline at end of file diff --git a/samples/sky/Sample_LDRSky.ts b/samples/sky/Sample_LDRSky.ts index 75163317..c6f696bd 100644 --- a/samples/sky/Sample_LDRSky.ts +++ b/samples/sky/Sample_LDRSky.ts @@ -1,46 +1,21 @@ -import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, Texture, SkyRenderer, BoxGeometry, LitMaterial, MeshRenderer, Object3D } from "@orillusion/core"; +import { Scene3D, Object3DUtil, Engine3D, SkyRenderer } from "@orillusion/core"; +import { createExampleScene } from "@samples/utils/ExampleScene"; // sample to replace ldr sky map class Sample_LDRSky { - private _scene: Scene3D; - private _originTexture: Texture; - private _externalTexture: Texture; - private _useExternal: boolean = false; async run() { // init engine await Engine3D.init({}); - // init scene - this._scene = new Scene3D(); - let sky = this._scene.addComponent(SkyRenderer) + let scene: Scene3D = createExampleScene().scene; + let sky = scene.getOrAddComponent(SkyRenderer); sky.map = await Engine3D.res.loadLDRTextureCube('sky/LDR_sky.jpg') - sky.roughness = 0.2 - this._scene.envMap = sky.map - - // init camera3D - let mainCamera = CameraUtil.createCamera3D(null, this._scene); - mainCamera.perspective(60, Engine3D.aspect, 1, 2000.0); - - // camera controller - let hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController); - hoverCameraController.setCamera(45, -10, 10); // create a basic cube - let cubeObj = new Object3D(); - let mr = cubeObj.addComponent(MeshRenderer); - mr.geometry = new BoxGeometry(); - let mat = new LitMaterial(); - mr.material = mat; - this._scene.addChild(cubeObj); - - // init view3D - let view = new View3D(); - view.scene = this._scene; - view.camera = mainCamera; + scene.addChild(Object3DUtil.GetSingleCube(10, 10, 10, 0.6, 0.6, 0.6)); // start renderer - Engine3D.startRenderView(view); + Engine3D.startRenderView(scene.view); } } diff --git a/samples/sky/Sample_SolidColorSky.ts b/samples/sky/Sample_SolidColorSky.ts index 7fdb6efa..b668308b 100644 --- a/samples/sky/Sample_SolidColorSky.ts +++ b/samples/sky/Sample_SolidColorSky.ts @@ -1,48 +1,27 @@ import { GUIHelp } from "@orillusion/debug/GUIHelp"; -import { Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, Texture, Color, SolidColorSky, Object3DUtil, SkyRenderer, BoxGeometry, LitMaterial, MeshRenderer, Object3D } from "@orillusion/core"; +import { createExampleScene } from "@samples/utils/ExampleScene"; +import { SolidColorSky, Engine3D, SkyRenderer, Color, Object3DUtil } from "@orillusion/core"; // sample to display solid color sky class HDRSkyMap { - private _scene: Scene3D; - private _externalTexture: SolidColorSky; - private _originTexture: Texture; - private _useExternal: boolean = false; - async run() { // init engine await Engine3D.init({}); - + GUIHelp.init(); // init scene - this._scene = new Scene3D(); - // use default env lights - this._scene.addComponent(AtmosphericComponent) + let scene = createExampleScene().scene; // use solid color as background - let sky = this._scene.addComponent(SkyRenderer) - sky.map = new SolidColorSky(new Color(0.3, 0.3, 0.3, 1)) - - // init camera3D - let mainCamera = CameraUtil.createCamera3D(null, this._scene); - mainCamera.perspective(60, Engine3D.aspect, 1, 2000.0); - - // camera controller - let hoverCameraController = mainCamera.object3D.addComponent(HoverCameraController); - hoverCameraController.setCamera(45, -10, 10); - + let sky = scene.getOrAddComponent(SkyRenderer); + sky.map = new SolidColorSky(new Color(0.3, 0.5, 0.3, 1)); + //gui + GUIHelp.addColor(sky.map, 'color'); + GUIHelp.open(); + GUIHelp.endFolder(); // create a basic cube - let cubeObj = new Object3D(); - let mr = cubeObj.addComponent(MeshRenderer); - mr.geometry = new BoxGeometry(); - let mat = new LitMaterial(); - mr.material = mat; - this._scene.addChild(cubeObj); - - // init view3D - let view = new View3D(); - view.scene = this._scene; - view.camera = mainCamera; + scene.addChild(Object3DUtil.GetSingleCube(10, 10, 10, 0.6, 0.6, 0.6)); // start renderer - Engine3D.startRenderView(view); + Engine3D.startRenderView(scene.view); } } diff --git a/samples/utils/ExampleScene.ts b/samples/utils/ExampleScene.ts index 3b0810bd..2168acac 100644 --- a/samples/utils/ExampleScene.ts +++ b/samples/utils/ExampleScene.ts @@ -51,7 +51,7 @@ export function createSceneParam(): ExampleSceneParam { far: 5000, distance: 100, fov: 60, - pitch: -30, + pitch: -15, roll: -30, }, diff --git a/src/assets/shader/sky/CubeSky_Shader.ts b/src/assets/shader/sky/CubeSky_Shader.ts index ce51b86f..6e901642 100644 --- a/src/assets/shader/sky/CubeSky_Shader.ts +++ b/src/assets/shader/sky/CubeSky_Shader.ts @@ -77,8 +77,11 @@ export class CubeSky_Shader { @fragment fn main(@location(0) fragUV: vec2, @location(1) vWorldPos: vec4, @location(2) vWorldNormal: vec3) -> FragmentOutput { let maxLevel: u32 = textureNumLevels(baseMap); - let textureColor:vec3 = textureSampleLevel(baseMap, baseMapSampler, normalize(vWorldPos.xyz), global.roughness * f32(maxLevel) ).xyz; - let o_Target: vec4 = vec4(LinearToGammaSpace(textureColor),1.0) * globalUniform.skyExposure ; + var textureColor:vec3 = textureSampleLevel(baseMap, baseMapSampler, normalize(vWorldPos.xyz), global.roughness * f32(maxLevel) ).xyz; + #if IS_HDR_SKY + textureColor = LinearToGammaSpace(textureColor); + #endif + let o_Target: vec4 =vec4(textureColor, 1.0) * globalUniform.skyExposure ; var normal_rgba8unorm = (vWorldNormal + 1.0) * 0.5; normal_rgba8unorm = clamp(normal_rgba8unorm, vec3(0.0), vec3(1.0)); diff --git a/src/gfx/graphics/webGpu/core/texture/Texture.ts b/src/gfx/graphics/webGpu/core/texture/Texture.ts index 6d551a90..8d3b90ee 100644 --- a/src/gfx/graphics/webGpu/core/texture/Texture.ts +++ b/src/gfx/graphics/webGpu/core/texture/Texture.ts @@ -120,6 +120,7 @@ export class Texture implements GPUSamplerDescriptor { * whether is video texture */ public isVideoTexture?: boolean; + public isHDRTexture?: boolean; private _useMipmap: boolean = false; diff --git a/src/index.ts b/src/index.ts index 1380d7e4..6363ced6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -453,6 +453,7 @@ export * from "./textures/HDRTexture" export * from "./textures/HDRTextureCube" export * from "./textures/LDRTextureCube" export * from "./textures/SolidColorSky" +export * from "./textures/TextureCubeFaceData" export * from "./textures/Uint16Texture" export * from "./textures/Uint8ArrayTexture" export * from "./textures/VirtualTexture" diff --git a/src/materials/SkyMaterial.ts b/src/materials/SkyMaterial.ts index 508b15ab..cbb30b53 100644 --- a/src/materials/SkyMaterial.ts +++ b/src/materials/SkyMaterial.ts @@ -29,13 +29,23 @@ export class SkyMaterial extends MaterialBase { shaderState.depthCompare = GPUCompareFunction.less; } - // public get baseMap(): Texture { - // return this.renderShader.textures[0]; - // } + /** + * Set base map(main map) + */ + public set baseMap(texture: Texture) { + super.baseMap = texture; + const key = 'IS_HDR_SKY'; + if (this.renderShader.defineValue[key] != texture?.isHDRTexture) { + this.renderShader.setDefine(key, texture?.isHDRTexture ? true : false); + } + } - // public set baseMap(value: Texture) { - // this.renderShader.setTexture( `baseMap` , value ); - // } + /** + * Get base map(main map) + */ + public get baseMap(): Texture { + return super.baseMap; + } public set envMap(texture: Texture) { //not need env texture diff --git a/src/textures/AtmosphericScatteringSky.ts b/src/textures/AtmosphericScatteringSky.ts index b3d2683f..a0536b60 100644 --- a/src/textures/AtmosphericScatteringSky.ts +++ b/src/textures/AtmosphericScatteringSky.ts @@ -1,11 +1,11 @@ -import { Color } from '..'; import { AtmosphericScatteringSky_shader } from '../assets/shader/sky/AtmosphericScatteringSky_shader'; import { UniformGPUBuffer } from '../gfx/graphics/webGpu/core/buffer/UniformGPUBuffer'; import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { ComputeShader } from '../gfx/graphics/webGpu/shader/ComputeShader'; import { GPUTextureFormat } from '../gfx/graphics/webGpu/WebGPUConst'; import { GPUContext } from '../gfx/renderJob/GPUContext'; -import { HDRTextureCube } from './HDRTextureCube'; +import { Color } from '../math/Color'; +import { LDRTextureCube } from './LDRTextureCube'; import { VirtualTexture } from './VirtualTexture'; /** * AtmosphericScattering Sky Setting @@ -13,12 +13,12 @@ import { VirtualTexture } from './VirtualTexture'; */ export class AtmosphericScatteringSkySetting { public sunRadius: number = 500.0; - public sunRadiance: number = 10.0; + public sunRadiance: number = 11.0; public mieG: number = 0.76; public mieHeight: number = 1200; public eyePos: number = 1500; public sunX: number = 0.55; - public sunY: number = 0.54; + public sunY: number = 0.56; public sunBrightness: number = 1.0; public displaySun: boolean = true; public defaultTextureCubeSize: number = 512; @@ -30,7 +30,7 @@ export class AtmosphericScatteringSkySetting { * Atmospheric Scattering Sky Texture * @group Texture */ -export class AtmosphericScatteringSky extends HDRTextureCube { +export class AtmosphericScatteringSky extends LDRTextureCube { private _internalTexture: AtmosphericTexture2D; private _cubeSize: number; public readonly setting: AtmosphericScatteringSkySetting; @@ -61,11 +61,9 @@ export class AtmosphericScatteringSky extends HDRTextureCube { */ public apply(): this { this._internalTexture.update(this.setting); - this.uploadErpTexture(this._internalTexture); + this._faceData.uploadErpTexture(this._internalTexture); return this; } - - } /** diff --git a/src/textures/HDRTexture.ts b/src/textures/HDRTexture.ts index 19d1a757..b128203a 100644 --- a/src/textures/HDRTexture.ts +++ b/src/textures/HDRTexture.ts @@ -13,6 +13,7 @@ export class HDRTexture extends Texture { constructor() { super(32, 32, null); + this.isHDRTexture = true; } /** diff --git a/src/textures/HDRTextureCube.ts b/src/textures/HDRTextureCube.ts index dae21a01..57bf5820 100644 --- a/src/textures/HDRTextureCube.ts +++ b/src/textures/HDRTextureCube.ts @@ -1,5 +1,4 @@ import { ErpImage2CubeMap } from '../gfx/generate/convert/ErpImage2CubeMap'; -import { IBLEnvMapCreator } from '../gfx/generate/convert/IBLEnvMapCreator'; import { Texture } from '../gfx/graphics/webGpu/core/texture/Texture'; import { TextureCube } from '../gfx/graphics/webGpu/core/texture/TextureCube'; import { GPUTextureFormat } from '../gfx/graphics/webGpu/WebGPUConst'; @@ -8,23 +7,25 @@ import { VirtualTexture } from './VirtualTexture'; import { FileLoader } from '../loader/FileLoader'; import { LoaderFunctions } from '../loader/LoaderFunctions'; import { RGBEParser } from '../loader/parser/RGBEParser'; +import { TextureCubeFaceData } from './TextureCubeFaceData'; /** * HDR TextureCube * @group Texture */ export class HDRTextureCube extends TextureCube { - private faceTextureRef: { [key: string]: { t: GPUTexture; v: GPUTextureView } }; private _url: string; + protected _faceData: TextureCubeFaceData; /** * create a cube texture, it's high dynamic range texture */ constructor() { super(); - this.faceTextureRef = {}; this.useMipmap = true; this.format = GPUTextureFormat.rgba16float; + this.isHDRTexture = true; + this._faceData = new TextureCubeFaceData(this); } /** @@ -64,87 +65,10 @@ export class HDRTextureCube extends TextureCube { this.textureDescriptor.dimension = '2d'; this.gpuSampler = webGPUContext.device.createSampler(this); - this.uploadErpTexture(texture); + this._faceData.uploadErpTexture(texture); return this; } - /** - * fill this texture by a texture2D, which is a 360 panorama image - * @param texture a panorama image - * @returns - */ - public uploadErpTexture(texture: Texture): this { - let gpuSource = this.getGpuSource(0); - ErpImage2CubeMap.makeTextureCube(texture, this.width, gpuSource.v); - // this.uploadMipmap(0, maxSize, faceTextures); - // this.generateMipmap(); - this.generateMipmap(texture); - return this; - } - - /** - * fill this texture by a texture2D, which is a 360 panorama image - * assign mipmap level - * @param mip mipmap level - * @param texture a panorama image - * @returns - */ - public uploadTexture(mip: number, texture: Texture): this { - let gpuSource = this.getGpuSource(mip); - ErpImage2CubeMap.makeTextureCube(texture, this.width, gpuSource.v); - return this; - } - - /** - * get GPU texture raw data - * @param mip mipmap level - * @returns GPU texture raw data, including t: GPUTexture and v: GPUTextureView - */ - private getGpuSource(mip: number): { t: GPUTexture; v: GPUTextureView } { - let source: { t: GPUTexture; v: GPUTextureView } = this.faceTextureRef[mip]; - if (!source) { - source = { - t: this.getGPUTexture(), - v: this.getGPUTexture().createView({ - format: this.format, - dimension: '2d-array', - baseMipLevel: mip, - mipLevelCount: 1, - arrayLayerCount: 6, - }), - }; - this.faceTextureRef[mip] = source; - } - return source; - } - - /** - * Generate Mipmap - * @param texture - */ - private generateMipmap(texture: Texture) { - let mipmap: number = 1; - while (mipmap < this.mipmapCount) { - this.generateMipmapAtLevel(mipmap, texture); - mipmap++; - } - } - - /** - * Generate a specified level of Mipmap - * @param mipmap mipmap level - * @param erpTexture ERP Texture Object - * @param pow power - */ - private generateMipmapAtLevel(mipmap: number, erpTexture: Texture, pow: number = 3.0): void { - let mipFaceSize = this.width / Math.pow(2, mipmap); - let image = { width: mipFaceSize, height: mipFaceSize, erpTexture: erpTexture }; - let roughness = (mipmap + 1) / this.mipmapCount; - roughness = Math.pow(roughness, pow); - let gpuSource = this.getGpuSource(mipmap); - IBLEnvMapCreator.importantSample(image, mipFaceSize, roughness, gpuSource.v); - } - /** * load texture data from web url, which is a 360 panorama image diff --git a/src/textures/LDRTextureCube.ts b/src/textures/LDRTextureCube.ts index 575becb1..e3094abe 100644 --- a/src/textures/LDRTextureCube.ts +++ b/src/textures/LDRTextureCube.ts @@ -1,19 +1,18 @@ -import { ErpImage2CubeMap } from "../gfx/generate/convert/ErpImage2CubeMap"; -import { IBLEnvMapCreator } from "../gfx/generate/convert/IBLEnvMapCreator"; import { GPUTextureFormat } from "../gfx/graphics/webGpu/WebGPUConst"; import { webGPUContext } from "../gfx/graphics/webGpu/Context3D"; import { Texture } from "../gfx/graphics/webGpu/core/texture/Texture"; import { TextureCube } from "../gfx/graphics/webGpu/core/texture/TextureCube"; import { LoaderFunctions } from "../loader/LoaderFunctions"; import { BitmapTexture2D } from "./BitmapTexture2D"; +import { TextureCubeFaceData } from "./TextureCubeFaceData"; /** * LDRTextureCube: create a cube texture, it's low dynamic range texture * @group Texture */ export class LDRTextureCube extends TextureCube { - private _faceTextureRef: { [key: string]: { t: GPUTexture; v: GPUTextureView } }; + protected _faceData: TextureCubeFaceData; private _url: string; /** * constructor: create a cube texture, it's low dynamic range texture @@ -24,9 +23,9 @@ export class LDRTextureCube extends TextureCube { } constructor() { super(); - this._faceTextureRef = {}; this.useMipmap = true; this.format = GPUTextureFormat.rgba16float; + this._faceData = new TextureCubeFaceData(this); } @@ -78,70 +77,11 @@ export class LDRTextureCube extends TextureCube { this.textureDescriptor.dimension = '2d'; this.gpuSampler = webGPUContext.device.createSampler(this); - this.uploadErpTexture(texture); + this._faceData.uploadErpTexture(texture); return this; } - /** - * @private - * @param texture texture reference - * @returns this - */ - private uploadErpTexture(texture: Texture): this { - let gpuSource = this.getGpuSource(0); - ErpImage2CubeMap.makeTextureCube(texture, this.width, gpuSource.v); - this.generateMipmap(texture); - return this; - } - /** - * @priate get GPU texture raw data - * @param mip mipmap level - * @returns GPU texture raw data, including t: GPUTexture and v: GPUTextureView - */ - private getGpuSource(mip: number): { t: GPUTexture; v: GPUTextureView } { - let source = this._faceTextureRef[mip]; - if (!source) { - source = { - t: this.getGPUTexture(), - v: this.getGPUTexture().createView({ - format: this.format, - dimension: '2d-array', - baseMipLevel: mip, - mipLevelCount: 1, - arrayLayerCount: 6, - }), - }; - this._faceTextureRef[mip] = source; - } - return source; - } - /** - * @private generateMipmap - * @param texture texture reference - */ - private generateMipmap(texture: Texture) { - let mipmap: number = 1; - while (mipmap < this.mipmapCount) { - this.generateMipmapAtLevel(mipmap, texture); - mipmap++; - } - } - - /** - * @private Generate a specified level of Mipmap - * @param mipmap mipmap level - * @param erpTexture ERP Texture Object - * @param pow power - */ - private generateMipmapAtLevel(mipmap: number, erpTexture: Texture, pow: number = 3.0): void { - let mipFaceSize = this.width / Math.pow(2, mipmap); - let image = { width: mipFaceSize, height: mipFaceSize, erpTexture: erpTexture }; - let roughness = (mipmap + 1) / this.mipmapCount; - roughness = Math.pow(roughness, pow); - let gpuSource = this.getGpuSource(mipmap); - IBLEnvMapCreator.importantSample(image, mipFaceSize, roughness, gpuSource.v); - } } diff --git a/src/textures/SolidColorSky.ts b/src/textures/SolidColorSky.ts index 55db9b36..17ee0333 100644 --- a/src/textures/SolidColorSky.ts +++ b/src/textures/SolidColorSky.ts @@ -2,13 +2,13 @@ import { Engine3D } from '../Engine3D'; import { Color } from '../math/Color'; import { Float16ArrayTexture } from './Float16ArrayTexture'; -import { HDRTextureCube } from './HDRTextureCube'; +import { LDRTextureCube } from './LDRTextureCube'; /** * create a cube texture, which filled by solid color. * @group Texture */ -export class SolidColorSky extends HDRTextureCube { +export class SolidColorSky extends LDRTextureCube { private _internalTexture: Float16ArrayTexture; private readonly _minSize = 32; private _skyColor: Color; @@ -34,7 +34,7 @@ export class SolidColorSky extends HDRTextureCube { this._skyColor = color; Engine3D.res.fillColor(this._internalTexture.floatArray, this._minSize, this._minSize, this.color.r, this.color.g, this.color.b, this.color.a); this._internalTexture.updateTexture(this._minSize, this._minSize, this._internalTexture.floatArray, false); - this.uploadTexture(0, this._internalTexture); + this._faceData.uploadTexture(0, this._internalTexture); return this; } diff --git a/src/textures/TextureCubeFaceData.ts b/src/textures/TextureCubeFaceData.ts new file mode 100644 index 00000000..1ba18bd3 --- /dev/null +++ b/src/textures/TextureCubeFaceData.ts @@ -0,0 +1,91 @@ +import { ErpImage2CubeMap } from "../gfx/generate/convert/ErpImage2CubeMap"; +import { IBLEnvMapCreator } from "../gfx/generate/convert/IBLEnvMapCreator"; +import { Texture } from "../gfx/graphics/webGpu/core/texture/Texture"; + +export class TextureCubeFaceData { + public faceTextureRef: { [key: string]: { t: GPUTexture; v: GPUTextureView } }; + + private _texture: Texture; + constructor(texture: Texture) { + this._texture = texture; + this.faceTextureRef = {}; + + } + + /** + * fill this texture by a texture2D, which is a 360 panorama image + * assign mipmap level + * @param mip mipmap level + * @param texture a panorama image + * @returns + */ + public uploadTexture(mip: number, texture: Texture): this { + let gpuSource = this.getGpuSource(mip); + ErpImage2CubeMap.makeTextureCube(texture, this._texture.width, gpuSource.v); + return this; + } + + + /** + * @private + * @param texture texture reference + * @returns this + */ + public uploadErpTexture(texture: Texture): this { + let gpuSource = this.getGpuSource(0); + ErpImage2CubeMap.makeTextureCube(texture, this._texture.width, gpuSource.v); + this.generateMipmap(texture); + return this; + } + + /** + * get GPU texture raw data + * @param mip mipmap level + * @returns GPU texture raw data, including t: GPUTexture and v: GPUTextureView + */ + public getGpuSource(mip: number): { t: GPUTexture; v: GPUTextureView } { + let source: { t: GPUTexture; v: GPUTextureView } = this.faceTextureRef[mip]; + if (!source) { + source = { + t: this._texture.getGPUTexture(), + v: this._texture.getGPUTexture().createView({ + format: this._texture.format, + dimension: '2d-array', + baseMipLevel: mip, + mipLevelCount: 1, + arrayLayerCount: 6, + }), + }; + this.faceTextureRef[mip] = source; + } + return source; + } + + /** + * @private generateMipmap + * @param texture texture reference + */ + private generateMipmap(texture: Texture) { + let mipmap: number = 1; + while (mipmap < this._texture.mipmapCount) { + this.generateMipmapAtLevel(mipmap, texture); + mipmap++; + } + } + + /** + * @private Generate a specified level of Mipmap + * @param mipmap mipmap level + * @param erpTexture ERP Texture Object + * @param pow power + */ + private generateMipmapAtLevel(mipmap: number, erpTexture: Texture, pow: number = 3.0): void { + let mipFaceSize = this._texture.width / Math.pow(2, mipmap); + let image = { width: mipFaceSize, height: mipFaceSize, erpTexture: erpTexture }; + let roughness = (mipmap + 1) / this._texture.mipmapCount; + roughness = Math.pow(roughness, pow); + let gpuSource = this.getGpuSource(mipmap); + IBLEnvMapCreator.importantSample(image, mipFaceSize, roughness, gpuSource.v); + } + +} \ No newline at end of file