From 4ca35b576454cb52aee47ddbc271a4d36a906e78 Mon Sep 17 00:00:00 2001 From: OldGentleMan Date: Wed, 1 Nov 2023 13:51:10 +0800 Subject: [PATCH] fix: fix gltf sample (#321) add graphic mesh material data fix gltf sample fix emissive color fix image material fix chromaKey material --- packages/media-extention/ChromaKeyMaterial.ts | 79 ++++---- packages/media-extention/ImageMaterial.ts | 37 ++-- packages/media-extention/VideoMaterial.ts | 1 - samples/graphic/Sample_GraphicMesh_7.ts | 23 +-- samples/graphic/Sample_GraphicMesh_Color.ts | 173 +++++++++++++++++ .../graphic/Sample_GraphicMesh_SpriteSheet.ts | 179 ++++++++++++++++++ samples/loader/Sample_LoadGLB.ts | 47 +++-- samples/material/Sample_ClearCoat.ts | 2 +- samples/utils/ExampleScene.ts | 6 +- .../core/struct/VertexAttributeIndexShader.ts | 5 + src/assets/shader/lighting/BxDF_frag.ts | 4 +- .../shader/materials/UnLitTextureArray.ts | 6 +- .../graphic/new/Graphic3DMeshRenderer.ts | 34 +++- .../parser/gltf/GLTFSubParserConverter.ts | 2 +- src/materials/LitMaterial.ts | 47 +++++ src/materials/SkyMaterial.ts | 2 +- src/math/Color.ts | 16 ++ src/math/UV.ts | 9 + src/textures/BitmapTexture2DArray.ts | 2 +- 19 files changed, 562 insertions(+), 112 deletions(-) create mode 100644 samples/graphic/Sample_GraphicMesh_Color.ts create mode 100644 samples/graphic/Sample_GraphicMesh_SpriteSheet.ts diff --git a/packages/media-extention/ChromaKeyMaterial.ts b/packages/media-extention/ChromaKeyMaterial.ts index c22c7e80..2830ff87 100644 --- a/packages/media-extention/ChromaKeyMaterial.ts +++ b/packages/media-extention/ChromaKeyMaterial.ts @@ -1,4 +1,4 @@ -import { Engine3D, ShaderLib, Vector4, Color, BlendMode, registerMaterial, Material, RenderShaderPass, Texture } from "@orillusion/core"; +import { Engine3D, ShaderLib, Vector4, Color, BlendMode, registerMaterial, Material, RenderShaderPass, Texture, Shader, PassType } from "@orillusion/core"; import { ChromaKeyShader } from "./ChromaKeyShader"; /** @@ -14,33 +14,38 @@ export class ChromaKeyMaterial extends Material { super(); ShaderLib.register("ChromaKeyShader", ChromaKeyShader); - this.defaultPass = new RenderShaderPass( + let newShader = new Shader(); + + let colorPass = new RenderShaderPass( `ChromaKeyShader`, `ChromaKeyShader` ); - this.defaultPass.setShaderEntry(`VertMain`, `FragMain`); + colorPass.setShaderEntry(`VertMain`, `FragMain`); + colorPass.passType = PassType.COLOR; - this.defaultPass.setUniformVector4( + colorPass.setUniformVector4( `transformUV1`, new Vector4(0, 0, 1, 1) ); - this.defaultPass.setUniformVector4( + colorPass.setUniformVector4( `transformUV2`, new Vector4(0, 0, 1, 1) ); - this.defaultPass.setUniformColor(`baseColor`, new Color()); - this.defaultPass.setUniformVector4(`rectClip`, new Vector4(0, 0, 0, 0)); - this.defaultPass.setUniformFloat(`alphaCutoff`, 0.5); - - this.defaultPass.setUniformColor(`keyColor`, new Color(0, 1, 0, 0)); - this.defaultPass.setUniformFloat(`colorCutoff`, 0.4); - this.defaultPass.setUniformFloat(`colorFeathering`, 0.5); - this.defaultPass.setUniformFloat(`maskFeathering`, 1); - this.defaultPass.setUniformFloat(`sharpening`, 0.5); - this.defaultPass.setUniformFloat(`despoil`, 0.6); - this.defaultPass.setUniformFloat(`despoilLuminanceAdd`, 0); - - let shaderState = this.defaultPass.shaderState; + colorPass.setUniformColor(`baseColor`, new Color()); + colorPass.setUniformVector4(`rectClip`, new Vector4(0, 0, 0, 0)); + colorPass.setUniformFloat(`alphaCutoff`, 0.5); + + colorPass.setUniformColor(`keyColor`, new Color(0, 1, 0, 0)); + colorPass.setUniformFloat(`colorCutoff`, 0.4); + colorPass.setUniformFloat(`colorFeathering`, 0.5); + colorPass.setUniformFloat(`maskFeathering`, 1); + colorPass.setUniformFloat(`sharpening`, 0.5); + colorPass.setUniformFloat(`despoil`, 0.6); + colorPass.setUniformFloat(`despoilLuminanceAdd`, 0); + + newShader.addRenderPass(colorPass); + + let shaderState = colorPass.shaderState; shaderState.acceptShadow = false; shaderState.receiveEnv = false; shaderState.acceptGI = false; @@ -50,127 +55,127 @@ export class ChromaKeyMaterial extends Material { shaderState.blendMode = BlendMode.ALPHA; // default value - this.defaultPass.setTexture(`baseMap`, Engine3D.res.whiteTexture); + this.shader.setTexture(`baseMap`, Engine3D.res.whiteTexture); } public set baseMap(value: Texture) { - this.defaultPass.setTexture(`baseMap`, value); + this.shader.setTexture(`baseMap`, value); } public get baseMap() { - return this.defaultPass.getTexture(`baseMap`); + return this.shader.getTexture(`baseMap`); } /** * Set the clip rect area */ public set rectClip(value: Vector4) { - this.defaultPass.uniforms[`rectClip`].vector4 = value; + this.shader.setUniformVector4(`rectClip`, value); } /** * Get current clip rect area */ public get rectClip(): Vector4 { - return this.defaultPass.uniforms[`rectClip`].vector4; + return this.shader.getUniformVector4(`rectClip`); } /** * Set the chromakey color */ public set keyColor(value: Color) { - this.defaultPass.uniforms[`keyColor`].color = value; + this.shader.setUniformColor(`keyColor`, value); } /** * Get the chromakey color */ public get keyColor(): Color { - return this.defaultPass.uniforms[`keyColor`].color; + return this.shader.getUniformColor(`keyColor`); } /** * Set the color cutoff factor */ public set colorCutoff(value: number) { - this.defaultPass.uniforms[`colorCutoff`].value = value; + this.shader.setUniformFloat(`colorCutoff`, value); } /** * Get the color cutoff factor */ public get colorCutoff(): number { - return this.defaultPass.uniforms[`colorCutoff`].value; + return this.shader.getUniformFloat(`colorCutoff`); } /** * Set the color feather factor */ public set colorFeathering(value: number) { - this.defaultPass.uniforms[`colorFeathering`].value = value; + this.shader.setUniformFloat(`colorFeathering`, value); } /** * Get the color feather factor */ public get colorFeathering(): number { - return this.defaultPass.uniforms[`colorFeathering`].value; + return this.shader.getUniformFloat(`colorFeathering`); } /** * Set the mask feather factor */ public set maskFeathering(value: number) { - this.defaultPass.uniforms[`maskFeathering`].value = value; + this.shader.setUniformFloat(`maskFeathering`, value); } /** * Get the mask feather factor */ public get maskFeathering(): number { - return this.defaultPass.uniforms[`maskFeathering`].value; + return this.shader.getUniformFloat(`maskFeathering`); } /** * Set the sharpen factor */ public set sharpening(value: number) { - this.defaultPass.uniforms[`sharpening`].value = value; + this.shader.setUniformFloat(`sharpening`, value); } /** * Get the sharpen factor */ public get sharpening(): number { - return this.defaultPass.uniforms[`sharpening`].value; + return this.shader.getUniformFloat(`sharpening`); } /** * Set the despoil factor */ public set despoil(value: number) { - this.defaultPass.uniforms[`despoil`].value = value; + this.shader.setUniformFloat(`despoil`, value); } /** * Get the despoil factor */ public get despoil(): number { - return this.defaultPass.uniforms[`despoil`].value; + return this.shader.getUniformFloat(`despoil`); } /** * Set the despoil luminance factor */ public set despoilLuminanceAdd(value: number) { - this.defaultPass.uniforms[`despoilLuminanceAdd`].value = value; + this.shader.setUniformFloat(`despoilLuminanceAdd`, value); } /** * Get the despoil luminance factor */ public get despoilLuminanceAdd(): number { - return this.defaultPass.uniforms[`despoilLuminanceAdd`].value; + return this.shader.getUniformFloat(`despoilLuminanceAdd`); } /** diff --git a/packages/media-extention/ImageMaterial.ts b/packages/media-extention/ImageMaterial.ts index 7c396d18..cd09b58e 100644 --- a/packages/media-extention/ImageMaterial.ts +++ b/packages/media-extention/ImageMaterial.ts @@ -1,4 +1,4 @@ -import { Engine3D, ShaderLib, Vector4, Color, Texture, Material, RenderShaderPass } from "@orillusion/core"; +import { Engine3D, ShaderLib, Vector4, Color, Texture, Material, RenderShaderPass, Shader, PassType } from "@orillusion/core"; import ImageMaterialShader from "./ImageMaterialShader.wgsl?raw"; @@ -15,60 +15,65 @@ export class ImageMaterial extends Material { constructor() { super(); ShaderLib.register("ImageMaterialShader", ImageMaterialShader); - this.defaultPass = new RenderShaderPass(`ImageMaterialShader`, `ImageMaterialShader`); - this.defaultPass.setShaderEntry(`VertMain`, `FragMain`) - this.defaultPass.setUniformVector4(`transformUV1`, new Vector4(0, 0, 1, 1)); - this.defaultPass.setUniformVector4(`transformUV2`, new Vector4(0, 0, 1, 1)); - this.defaultPass.setUniformColor(`baseColor`, new Color()); - this.defaultPass.setUniformVector4(`rectClip`, new Vector4(0, 0, 0, 0)); - this.defaultPass.setUniformFloat(`alphaCutoff`, 0.5); + let newShader = new Shader(); - let shaderState = this.defaultPass.shaderState; + let defaultPass = new RenderShaderPass(`ImageMaterialShader`, `ImageMaterialShader`); + defaultPass.passType = PassType.COLOR; + defaultPass.setShaderEntry(`VertMain`, `FragMain`) + defaultPass.setUniformVector4(`transformUV1`, new Vector4(0, 0, 1, 1)); + defaultPass.setUniformVector4(`transformUV2`, new Vector4(0, 0, 1, 1)); + defaultPass.setUniformColor(`baseColor`, new Color()); + defaultPass.setUniformVector4(`rectClip`, new Vector4(0, 0, 0, 0)); + defaultPass.setUniformFloat(`alphaCutoff`, 0.5); + newShader.addRenderPass(defaultPass); + + let shaderState = defaultPass.shaderState; shaderState.acceptShadow = false; shaderState.receiveEnv = false; shaderState.acceptGI = false; shaderState.useLight = false; shaderState.castShadow = false; shaderState.useZ = false; + this.shader = newShader; // default value - this.defaultPass.setTexture(`baseMap`, Engine3D.res.whiteTexture); + this.shader.setTexture(`baseMap`, Engine3D.res.whiteTexture); } public set baseMap(value: Texture) { - this.defaultPass.setTexture(`baseMap`, value); + this.shader.setTexture(`baseMap`, value); } public get baseMap() { - return this.defaultPass.getTexture(`baseMap`); + return this.shader.getTexture(`baseMap`); } /** * set base color (tint color) */ public set baseColor(color: Color) { - this.defaultPass.setUniformColor(`baseColor`, color); + this.shader.setUniformColor(`baseColor`, color); } /** * get base color (tint color) */ public get baseColor() { - return this.defaultPass.uniforms[`baseColor`].color; + return this.shader.getUniformColor(`baseColor`); } /** * Set the clip rect area */ public set rectClip(value: Vector4) { - this.defaultPass.uniforms[`rectClip`].vector4 = value; + this.shader.setUniformVector4(`rectClip`, value); } /** * Get the clip rect area */ public get rectClip(): Vector4 { - return this.defaultPass.uniforms[`rectClip`].vector4; + return this.shader.getUniformVector4(`rectClip`); } /** diff --git a/packages/media-extention/VideoMaterial.ts b/packages/media-extention/VideoMaterial.ts index acc01e85..05e0c977 100644 --- a/packages/media-extention/VideoMaterial.ts +++ b/packages/media-extention/VideoMaterial.ts @@ -22,7 +22,6 @@ export class VideoMaterial extends Material { colorPass.passType = PassType.COLOR; colorPass.setShaderEntry(`VertMain`, `FragMain`) - colorPass.setShaderEntry(`VertMain`, `FragMain`) colorPass.setUniformVector4(`transformUV1`, new Vector4(0, 0, 1, 1)); colorPass.setUniformVector4(`transformUV2`, new Vector4(0, 0, 1, 1)); colorPass.setUniformColor(`baseColor`, new Color()); diff --git a/samples/graphic/Sample_GraphicMesh_7.ts b/samples/graphic/Sample_GraphicMesh_7.ts index 7bfffc60..b753c7ea 100644 --- a/samples/graphic/Sample_GraphicMesh_7.ts +++ b/samples/graphic/Sample_GraphicMesh_7.ts @@ -55,8 +55,6 @@ export class Sample_GraphicMesh_7 { await this.initScene(); - - sky.relativeTransform = this.lightObj3D.transform; } @@ -91,32 +89,21 @@ export class Sample_GraphicMesh_7 { { this.width = 15; this.height = 15; - // let geometry = new BoxGeometry(1, 1, 1); let geometry = new PlaneGeometry(1, 1, 1, 1, Vector3.Z_AXIS); let mr = Graphic3DMesh.draw(this.scene, geometry, bitmapTexture2DArray, this.width * this.height); this.parts = mr.object3Ds; mr.material.blendMode = BlendMode.ADD; - // mr.material.doubleSide = true; mr.material.transparent = true; mr.material.depthWriteEnabled = false; mr.material.useBillboard = true; for (let i = 0; i < this.width * this.height; i++) { const element = this.parts[i]; - // mr.setTextureID(i, i % texts.length); - // mr.setTextureID(i, 52); mr.setTextureID(i, 0); - // mr.setTextureID(i, 39); - // mr.setTextureID(i, 18); - element.transform.scaleX = 5.5; element.transform.scaleY = 5.5; element.transform.scaleZ = 5.5; - - // let c = Color.random(); - // c.a = 0.55; - // this.colors.push(c); } let c1 = new Color(0.65, 0.1, 0.2, 0.15); @@ -142,25 +129,21 @@ export class Sample_GraphicMesh_7 { this.tmpArray.length = 0; for (let i = 0; i < this.parts.length; i++) { const element = this.parts[i]; - let tmp = this.sphericalFibonacci(i, this.parts.length); tmp.scaleBy(this.cafe); - element.transform.localPosition = tmp; - - // if (sc > this.cafe * 0.95) { this.tmpArray.push(element); - // } } for (let i = 0; i < this.tmpArray.length / 3; i++) { this.view.graphic3D.Clear(i.toString()); - this.view.graphic3D.drawLines(i.toString(), [ + this.view.graphic3D.drawLines(i.toString(), + [ this.tmpArray[i * 3 + 0].transform.worldPosition, this.tmpArray[i * 3 + 1].transform.worldPosition, this.tmpArray[i * 3 + 2].transform.worldPosition, ], - this.colors); + this.colors); } } } diff --git a/samples/graphic/Sample_GraphicMesh_Color.ts b/samples/graphic/Sample_GraphicMesh_Color.ts new file mode 100644 index 00000000..4bfc06f7 --- /dev/null +++ b/samples/graphic/Sample_GraphicMesh_Color.ts @@ -0,0 +1,173 @@ +import { GUIHelp } from "@orillusion/debug/GUIHelp"; +import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, SphereGeometry, VirtualTexture, GPUTextureFormat, UnLitMaterial, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode, Color, PostProcessingComponent, BloomPost, ColorUtil, Graphic3DMeshRenderer } from "@orillusion/core"; +import { GUIUtil } from "@samples/utils/GUIUtil"; +import { Stats } from "@orillusion/stats"; + +export class Sample_GraphicMesh_Color { + private lightObj3D: Object3D; + private scene: Scene3D; + private parts: Object3D[]; + private width: number; + private height: number; + private cafe: number = 47; + private frame: number = 16; + private view: View3D; + private colors: Color[]; + private tmpArray: any[] = []; + + private color1: Color ; + private color2: Color ; + graphicMeshRenderer: Graphic3DMeshRenderer; + + constructor() { } + + async run() { + + Matrix4.maxCount = 500000; + Matrix4.allocCount = 500000; + + await Engine3D.init({ beforeRender: () => this.update() }); + + Engine3D.setting.render.debug = true; + Engine3D.setting.shadow.shadowBound = 5; + + this.colors = []; + + GUIHelp.init(); + + this.scene = new Scene3D(); + this.scene.addComponent(Stats); + let sky = this.scene.addComponent(AtmosphericComponent); + sky.enable = false; + let camera = CameraUtil.createCamera3DObject(this.scene); + camera.perspective(60, Engine3D.aspect, 1, 5000.0); + + camera.object3D.addComponent(HoverCameraController).setCamera(30, 0, 120); + + this.view = new View3D(); + this.view.scene = this.scene; + this.view.camera = camera; + + Engine3D.startRenderView(this.view); + + GUIUtil.renderDebug(); + + let post = this.scene.addComponent(PostProcessingComponent); + let bloom = post.addPost(BloomPost); + bloom.bloomIntensity = 10.0 + GUIUtil.renderBloom(bloom); + + await this.initScene(); + + sky.relativeTransform = this.lightObj3D.transform; + } + + async initScene() { + /******** light *******/ + { + this.lightObj3D = new Object3D(); + this.lightObj3D.rotationX = 21; + this.lightObj3D.rotationY = 108; + this.lightObj3D.rotationZ = 10; + let directLight = this.lightObj3D.addComponent(DirectLight); + directLight.lightColor = KelvinUtil.color_temperature_to_rgb(5355); + directLight.castShadow = false; + directLight.intensity = 10; + GUIUtil.renderDirLight(directLight); + this.scene.addChild(this.lightObj3D); + } + + let texts = []; + + texts.push(await Engine3D.res.loadTexture("textures/128/star_0008.png") as BitmapTexture2D); + + let bitmapTexture2DArray = new BitmapTexture2DArray(texts[0].width, texts[0].height, texts.length); + bitmapTexture2DArray.setTextures(texts); + + let mat = new UnLitTexArrayMaterial(); + mat.baseMap = bitmapTexture2DArray; + mat.name = "LitMaterial"; + + GUIHelp.add(this, "cafe", 0.0, 100.0); + GUIHelp.add(this, "frame", 0.0, 100.0); + { + this.width = 15; + this.height = 15; + let geometry = new PlaneGeometry(1, 1, 1, 1, Vector3.Z_AXIS); + this.graphicMeshRenderer = Graphic3DMesh.draw(this.scene, geometry, bitmapTexture2DArray, this.width * this.height); + this.parts = this.graphicMeshRenderer.object3Ds; + + this.graphicMeshRenderer.material.blendMode = BlendMode.ADD; + this.graphicMeshRenderer.material.transparent = true; + this.graphicMeshRenderer.material.depthWriteEnabled = false; + this.graphicMeshRenderer.material.useBillboard = true; + + for (let i = 0; i < this.width * this.height; i++) { + const element = this.parts[i]; + this.graphicMeshRenderer.setTextureID(i, 0); + element.transform.scaleX = 5.5; + element.transform.scaleY = 5.5; + element.transform.scaleZ = 5.5; + } + + this.color1 = new Color(1.5, 0.1, 0.2, 1.0); + this.color2 = new Color(0.1, 0.1, 4.5, 1.0); + let c2 = new Color(1.0, 1.1, 0.2, 0.65); + this.colors.push(c2); + this.colors.push(c2); + this.colors.push(c2); + this.colors.push(c2); + this.colors.push(c2); + this.colors.push(c2); + } + + this.updateOnce(1000); + } + + update() { + this.updateOnce(Time.frame); + } + + updateOnce(engineFrame: number) { + if (this.parts) { + this.tmpArray.length = 0; + let len = this.parts.length ; + for (let i = 0; i < len; i++) { + const element = this.parts[i]; + let tmp = this.sphericalFibonacci(i, len); + tmp.scaleBy(this.cafe); + element.transform.localPosition = tmp; + this.tmpArray.push(element); + + let c = Color.lerp( Math.sin(engineFrame*0.001 + (i/len)), this.color1,this.color2, Color.COLOR_0 ); + this.graphicMeshRenderer.setBaseColor(i,c); + } + + for (let i = 0; i < this.tmpArray.length - 1; i++) { + this.view.graphic3D.Clear(i.toString()); + this.view.graphic3D.drawLines(i.toString(), [ + Vector3.ZERO, + this.tmpArray[i + 1].transform.worldPosition, + ], + this.colors); + } + } + } + + public madfrac(A: number, B: number): number { + return A * B - Math.floor(A * B); + } + + public sphericalFibonacci(i: number, n: number): Vector3 { + const PHI = Math.sqrt(5.0) * 0.5 + 0.5; + let phi = 2.0 * Math.PI * this.madfrac(i, PHI - 1); + let cosTheta = 1.0 - (2.0 * i + 1.0) * (1.0 / n); + let sinTheta = Math.sqrt(Math.max(Math.min(1.0 - cosTheta * cosTheta, 1.0), 0.0)); + + return new Vector3( + Math.cos(phi) * sinTheta, + Math.sin(phi) * sinTheta, + cosTheta); + } + +} diff --git a/samples/graphic/Sample_GraphicMesh_SpriteSheet.ts b/samples/graphic/Sample_GraphicMesh_SpriteSheet.ts new file mode 100644 index 00000000..03f21098 --- /dev/null +++ b/samples/graphic/Sample_GraphicMesh_SpriteSheet.ts @@ -0,0 +1,179 @@ +import { GUIHelp } from "@orillusion/debug/GUIHelp"; +import { Object3D, Scene3D, Engine3D, AtmosphericComponent, CameraUtil, HoverCameraController, View3D, DirectLight, KelvinUtil, LitMaterial, MeshRenderer, BoxGeometry, SphereGeometry, VirtualTexture, GPUTextureFormat, UnLitMaterial, UnLitTexArrayMaterial, BitmapTexture2DArray, BitmapTexture2D, PlaneGeometry, Vector3, Graphic3DMesh, Matrix4, Time, BlendMode, Color, PostProcessingComponent, BloomPost, ColorUtil, Graphic3DMeshRenderer, UV } from "@orillusion/core"; +import { GUIUtil } from "@samples/utils/GUIUtil"; +import { Stats } from "@orillusion/stats"; + +export class Sample_GraphicMesh_SpriteSheet { + private lightObj3D: Object3D; + private scene: Scene3D; + private parts: Object3D[]; + private width: number; + private height: number; + private cafe: number = 47; + private frame: number = 16; + private view: View3D; + private colors: Color[]; + private tmpArray: any[] = []; + + private color1: Color; + private color2: Color; + graphicMeshRenderer: Graphic3DMeshRenderer; + + constructor() { } + + async run() { + + Matrix4.maxCount = 500000; + Matrix4.allocCount = 500000; + + await Engine3D.init({ beforeRender: () => this.update() }); + + Engine3D.setting.render.debug = true; + Engine3D.setting.shadow.shadowBound = 5; + + this.colors = []; + + GUIHelp.init(); + + this.scene = new Scene3D(); + this.scene.addComponent(Stats); + let sky = this.scene.addComponent(AtmosphericComponent); + sky.enable = false; + let camera = CameraUtil.createCamera3DObject(this.scene); + camera.perspective(60, Engine3D.aspect, 1, 5000.0); + + camera.object3D.addComponent(HoverCameraController).setCamera(30, 0, 120); + + this.view = new View3D(); + this.view.scene = this.scene; + this.view.camera = camera; + + Engine3D.startRenderView(this.view); + + GUIUtil.renderDebug(); + + let post = this.scene.addComponent(PostProcessingComponent); + let bloom = post.addPost(BloomPost); + bloom.bloomIntensity = 10.0 + GUIUtil.renderBloom(bloom); + + await this.initScene(); + + sky.relativeTransform = this.lightObj3D.transform; + } + + async initScene() { + /******** light *******/ + { + this.lightObj3D = new Object3D(); + this.lightObj3D.rotationX = 21; + this.lightObj3D.rotationY = 108; + this.lightObj3D.rotationZ = 10; + let directLight = this.lightObj3D.addComponent(DirectLight); + directLight.lightColor = KelvinUtil.color_temperature_to_rgb(5355); + directLight.castShadow = false; + directLight.intensity = 10; + GUIUtil.renderDirLight(directLight); + this.scene.addChild(this.lightObj3D); + } + + let texts = []; + + // texts.push(await Engine3D.res.loadTexture("textures/spriteSheet/sequence_0031.png") as BitmapTexture2D); + // texts.push(await Engine3D.res.loadTexture("textures/spriteSheet/sequence_0050.png") as BitmapTexture2D); + // texts.push(await Engine3D.res.loadTexture("textures/spriteSheet/sequence_0036.png") as BitmapTexture2D); + // texts.push(await Engine3D.res.loadTexture("textures/spriteSheet/sequence_0053.png") as BitmapTexture2D); + // texts.push(await Engine3D.res.loadTexture("textures/spriteSheet/sequence_0041.png") as BitmapTexture2D); + texts.push(await Engine3D.res.loadTexture("textures/spriteSheet/sequence_0040.png") as BitmapTexture2D); + + let bitmapTexture2DArray = new BitmapTexture2DArray(texts[0].width, texts[0].height, texts.length); + bitmapTexture2DArray.setTextures(texts); + + let mat = new UnLitTexArrayMaterial(); + mat.baseMap = bitmapTexture2DArray; + mat.name = "LitMaterial"; + + GUIHelp.add(this, "cafe", 0.0, 100.0); + GUIHelp.add(this, "frame", 0.0, 100.0); + { + this.width = 15; + this.height = 15; + let geometry = new PlaneGeometry(1, 1, 1, 1, Vector3.Z_AXIS); + this.graphicMeshRenderer = Graphic3DMesh.draw(this.scene, geometry, bitmapTexture2DArray, this.width * this.height); + this.parts = this.graphicMeshRenderer.object3Ds; + + this.graphicMeshRenderer.material.blendMode = BlendMode.ADD; + this.graphicMeshRenderer.material.transparent = true; + this.graphicMeshRenderer.material.depthWriteEnabled = false; + this.graphicMeshRenderer.material.useBillboard = true; + + for (let i = 0; i < this.width * this.height; i++) { + const element = this.parts[i]; + this.graphicMeshRenderer.setTextureID(i, 0); + element.transform.scaleX = 5.5; + element.transform.scaleY = 5.5; + element.transform.scaleZ = 5.5; + } + + this.color1 = new Color(1.5, 0.1, 0.2, 1.0); + this.color2 = new Color(0.1, 0.1, 4.5, 1.0); + let c2 = new Color(1.0, 1.1, 0.2, 0.45); + this.colors.push(c2); + this.colors.push(c2); + this.colors.push(c2); + this.colors.push(c2); + this.colors.push(c2); + this.colors.push(c2); + } + + this.updateOnce(1000); + } + + update() { + this.updateOnce(Time.frame); + } + + updateOnce(engineFrame: number) { + if (this.parts) { + this.tmpArray.length = 0; + let len = this.parts.length; + for (let i = 0; i < len; i++) { + const element = this.parts[i]; + let tmp = this.sphericalFibonacci(i, len); + tmp.scaleBy(this.cafe); + element.transform.localPosition = tmp; + this.tmpArray.push(element); + + // let c = Color.lerp(Math.sin(engineFrame * 0.001 + (i / len)), this.color1, this.color2, Color.COLOR_0); + // this.graphicMeshRenderer.setBaseColor(i, c); + this.graphicMeshRenderer.setUVRect(i, UV.getUVSheet((i / len) * 100 + engineFrame * 0.08, 3, 3)); + } + + for (let i = 0; i < this.tmpArray.length - 1; i++) { + this.view.graphic3D.Clear(i.toString()); + this.view.graphic3D.drawLines(i.toString(), [ + Vector3.ZERO, + this.tmpArray[i + 1].transform.worldPosition, + ], + this.colors); + } + } + } + + public madfrac(A: number, B: number): number { + return A * B - Math.floor(A * B); + } + + public sphericalFibonacci(i: number, n: number): Vector3 { + const PHI = Math.sqrt(5.0) * 0.5 + 0.5; + let phi = 2.0 * Math.PI * this.madfrac(i, PHI - 1); + let cosTheta = 1.0 - (2.0 * i + 1.0) * (1.0 / n); + let sinTheta = Math.sqrt(Math.max(Math.min(1.0 - cosTheta * cosTheta, 1.0), 0.0)); + + return new Vector3( + Math.cos(phi) * sinTheta, + Math.sin(phi) * sinTheta, + cosTheta); + } + +} diff --git a/samples/loader/Sample_LoadGLB.ts b/samples/loader/Sample_LoadGLB.ts index 2ef82b3b..d24ac932 100644 --- a/samples/loader/Sample_LoadGLB.ts +++ b/samples/loader/Sample_LoadGLB.ts @@ -83,14 +83,6 @@ export class Sample_LoadGLB { rotation: [180, 0, 0] } ) - list[`Mark-XLIV`] = JSON.stringify( - { - url: `gltfs/glb/Mark-XLIV.glb`, - scale: 0.1, - offset: [0, 0, 0], - rotation: [0, 0, 0] - } - ) list[`PotionBottle`] = JSON.stringify( { url: `gltfs/glb/PotionBottle.glb`, @@ -109,28 +101,33 @@ export class Sample_LoadGLB { ) let model: Object3D; + let { url, scale, offset, rotation } = JSON.parse(list[`HIE-Hand-Armor`]); + this.loadGLB(model, url, offset, scale, rotation); GUIHelp.add({ Model: `HIE-Hand-Armor` }, 'Model', list).onChange(async (v) => { let { url, scale, offset, rotation } = JSON.parse(v); - if (model) { - this.scene.removeChild(model); - } - model = (await Engine3D.res.loadGltf(url, { onProgress: (e) => this.onLoadProgress(e), onComplete: (e) => this.onComplete(e) })) as Object3D; - this.scene.addChild(model); - model.x = offset[0]; - model.y = offset[1]; - model.z = offset[2]; - - model.scaleX = scale; - model.scaleY = scale; - model.scaleZ = scale; - - model.rotationX = rotation[0]; - model.rotationY = rotation[1]; - model.rotationZ = rotation[2]; - + this.loadGLB(model, url, offset, scale, rotation); }); } + private async loadGLB(model: Object3D, url: string, offset: number[], scale: number, rotation: number[]) { + if (model) { + this.scene.removeChild(model); + } + model = (await Engine3D.res.loadGltf(url, { onProgress: (e) => this.onLoadProgress(e), onComplete: (e) => this.onComplete(e) })) as Object3D; + this.scene.addChild(model); + model.x = offset[0]; + model.y = offset[1]; + model.z = offset[2]; + + model.scaleX = scale; + model.scaleY = scale; + model.scaleZ = scale; + + model.rotationX = rotation[0]; + model.rotationY = rotation[1]; + model.rotationZ = rotation[2]; + } + onLoadProgress(e) { console.log(e); } diff --git a/samples/material/Sample_ClearCoat.ts b/samples/material/Sample_ClearCoat.ts index dedc92c5..3b7b013a 100644 --- a/samples/material/Sample_ClearCoat.ts +++ b/samples/material/Sample_ClearCoat.ts @@ -72,7 +72,7 @@ class Sample_ClearCoat { // model.transform.scaleZ = 10; // model.transform.y = -5; - let clearCoatRoughnessTex = await Engine3D.res.loadTexture("PBR/ClearCoatTest/T_Imperfections_Wipe_Mask.PNG"); + let clearCoatRoughnessTex = await Engine3D.res.loadTexture("materials/T_Imperfections_FingerPrints_Mask2.jpg"); // this.scene.addChild(model); let space = 50; diff --git a/samples/utils/ExampleScene.ts b/samples/utils/ExampleScene.ts index 1554b209..76f17251 100644 --- a/samples/utils/ExampleScene.ts +++ b/samples/utils/ExampleScene.ts @@ -48,10 +48,10 @@ let exampleSceneParam: ExampleSceneParam; export function createSceneParam(): ExampleSceneParam { let param: ExampleSceneParam = { camera: { - near: 1, - far: 5000, + near: 0.01, + far: 1000, distance: 100, - fov: 60, + fov: 45, pitch: -15, roll: -30, }, diff --git a/src/assets/shader/core/struct/VertexAttributeIndexShader.ts b/src/assets/shader/core/struct/VertexAttributeIndexShader.ts index 99821333..475785bf 100644 --- a/src/assets/shader/core/struct/VertexAttributeIndexShader.ts +++ b/src/assets/shader/core/struct/VertexAttributeIndexShader.ts @@ -34,6 +34,11 @@ export let VertexAttributeIndexShader: string = /*wgsl*/ ` struct GraphicNodeStruct{ matrixIndex:f32, texIndex:f32, + tex2Index:f32, + tex3Index:f32, + baseColor:vec4f, + emissiveColor:vec4f, + uvRect:vec4f, } var ORI_VertexOut: VertexOutput ; diff --git a/src/assets/shader/lighting/BxDF_frag.ts b/src/assets/shader/lighting/BxDF_frag.ts index d2d39a73..5544a3b7 100644 --- a/src/assets/shader/lighting/BxDF_frag.ts +++ b/src/assets/shader/lighting/BxDF_frag.ts @@ -134,7 +134,6 @@ export let BxDF_frag: string = /*wgsl*/ ` #endif var color = specColor + indirectResult ; - color += fragData.Emissive.xyz ; var clearCoatColor = vec3(0.0); #if USE_CLEARCOAT @@ -147,8 +146,7 @@ export let BxDF_frag: string = /*wgsl*/ ` #endif var retColor = (LinearToGammaSpace(color.rgb)); - // retColor += fragData.Emissive.xyz ; - // ORI_FragmentOutput.color = vec4( irradiance * min(fragData.Albedo.rgb,vec3f(1.0)) ,fragData.Albedo.a) ; + retColor += fragData.Emissive.xyz ; ORI_FragmentOutput.color = vec4( retColor.rgb * fragData.Albedo.a ,fragData.Albedo.a) ; } diff --git a/src/assets/shader/materials/UnLitTextureArray.ts b/src/assets/shader/materials/UnLitTextureArray.ts index ad161668..bc5bec6f 100644 --- a/src/assets/shader/materials/UnLitTextureArray.ts +++ b/src/assets/shader/materials/UnLitTextureArray.ts @@ -52,9 +52,10 @@ export let UnLitTextureArray: string = /*wgsl*/ ` // irradiance += (globalUniform.skyExposure * textureSampleLevel(prefilterMap, prefilterMapSampler, ORI_VertexVarying.vWorldNormal.xyz, 0.8 * (MAX_REFLECTION_LOD) ).rgb); graphicNode = graphicBuffer[u32(round(ORI_VertexVarying.index))]; - + var uv = transformUV1.zw * ORI_VertexVarying.fragUV0 + transformUV1.xy; - let color = textureSample(baseMap,baseMapSampler,uv, u32(round(graphicNode.texIndex)) ); + uv = graphicNode.uvRect.zw * uv.xy + graphicNode.uvRect.xy; + var color = textureSample(baseMap,baseMapSampler,uv, u32(round(graphicNode.texIndex)) ) * graphicNode.baseColor ; // let color = textureSample(baseMap,baseMapSampler,uv, u32(round(ORI_VertexVarying.index))); // ORI_ViewDir = normalize( globalUniform.CameraPos.xyz - ORI_VertexVarying.vWorldPos.xyz); @@ -62,6 +63,7 @@ export let UnLitTextureArray: string = /*wgsl*/ ` // irradiance = LinearToGammaSpace(irradiance.rgb) * color.rgb ;//* att ; + color += graphicNode.emissiveColor ; if(color.w < 0.5){ discard ; } diff --git a/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer.ts b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer.ts index 82ca2a14..b3e56f62 100644 --- a/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer.ts +++ b/src/gfx/renderJob/passRenderer/graphic/new/Graphic3DMeshRenderer.ts @@ -1,3 +1,4 @@ +import { Color, Vector4 } from "../../../../.."; import { MeshRenderer } from "../../../../../components/renderer/MeshRenderer"; import { View3D } from "../../../../../core/View3D"; import { Object3D } from "../../../../../core/entities/Object3D"; @@ -23,7 +24,8 @@ export class Graphic3DMeshRenderer extends MeshRenderer { mat.baseMap = tex; this.material = mat; - this.transformBuffer = new StorageGPUBuffer(num * 2, 0); + this.transformBuffer = new StorageGPUBuffer( num * (4 * 4) , 0); + // this.transformBuffer = new StorageGPUBuffer( num * 2 , 0); this.material.setStorageBuffer("graphicBuffer", this.transformBuffer); this.object3Ds = []; @@ -34,6 +36,11 @@ export class Graphic3DMeshRenderer extends MeshRenderer { this.transformBuffer.setFloat("matrix_" + i, element.transform.worldMatrix.index); this.transformBuffer.setFloat("texId_" + i, 1); + this.transformBuffer.setFloat("texId2_" + i, 1); + this.transformBuffer.setFloat("texId3_" + i, 1); + this.transformBuffer.setColor("baseColor_" + i, new Color() ); + this.transformBuffer.setColor("emissiveColor_" + i, new Color(0,0,0,0)); + this.transformBuffer.setVector4("uvRect_" + i, new Vector4(0,0,1,1) ); } this.transformBuffer.apply(); @@ -45,6 +52,31 @@ export class Graphic3DMeshRenderer extends MeshRenderer { this._onChange = true; } + // public setTexture2ID(i: number, id: number) { + // this.transformBuffer.setFloat("texId_" + i, id); + // this._onChange = true; + // } + + // public setTexture3ID(i: number, id: number) { + // this.transformBuffer.setFloat("texId_" + i, id); + // this._onChange = true; + // } + + public setBaseColor(i: number, color: Color) { + this.transformBuffer.setColor("baseColor_" + i, color); + this._onChange = true; + } + + public setEmissiveColor(i: number, color: Color) { + this.transformBuffer.setColor("emissiveColor_" + i, color); + this._onChange = true; + } + + public setUVRect(i: number, v: Vector4) { + this.transformBuffer.setVector4("uvRect_" + i, v); + this._onChange = true; + } + public onUpdate(view?: View3D) { if (this._onChange) { this._onChange = false; diff --git a/src/loader/parser/gltf/GLTFSubParserConverter.ts b/src/loader/parser/gltf/GLTFSubParserConverter.ts index 07d95f5b..99479482 100644 --- a/src/loader/parser/gltf/GLTFSubParserConverter.ts +++ b/src/loader/parser/gltf/GLTFSubParserConverter.ts @@ -180,7 +180,7 @@ export class GLTFSubParserConverter { let physicMaterial = (newMat = this.applyMaterialExtensions(primitive.material, newMat)); if (`enableBlend` in primitive.material) { if (primitive.material[`enableBlend`]) { - physicMaterial.blendMode = BlendMode.NORMAL; + physicMaterial.blendMode = BlendMode.SOFT_ADD; } else { physicMaterial.blendMode = BlendMode.NONE; } diff --git a/src/materials/LitMaterial.ts b/src/materials/LitMaterial.ts index 1a15c7be..ae7128ba 100644 --- a/src/materials/LitMaterial.ts +++ b/src/materials/LitMaterial.ts @@ -94,6 +94,53 @@ export class LitMaterial extends Material { return this.shader.getTexture(`aoMap`); } + public set clearCoatRoughnessMap(texture: Texture) { + this.shader.setTexture(`clearCoatRoughnessMap`, texture); + this.shader.setDefine(`USE_CLEARCOAT`, true); + this.shader.setDefine(`USE_CLEARCOAT_ROUGHNESS`, true); + } + + public get clearCoatRoughnessMap() { + return this.shader.getTexture(`clearCoatRoughnessMap`); + } + + public set clearcoatColor(value: Color) { + this.shader.setUniformColor(`clearcoatColor`, value); + this.shader.setDefine(`USE_CLEARCOAT`, true); + } + + public get clearcoatColor() { + return this.shader.getUniformColor(`clearcoatColor`); + } + + public set clearcoatWeight(value: number) { + this.shader.setUniformFloat(`clearcoatWeight`, value); + this.shader.setDefine(`USE_CLEARCOAT`, true); + } + + public get clearcoatWeight() { + return this.shader.getUniformFloat(`clearcoatWeight`); + } + + public set clearcoatFactor(value: number) { + this.shader.setUniformFloat(`clearcoatFactor`, value); + this.shader.setDefine(`USE_CLEARCOAT`, true); + } + + public get clearcoatFactor() { + return this.shader.getUniformFloat(`clearcoatFactor`); + } + + + public set clearcoatRoughnessFactor(value: number) { + this.shader.setUniformFloat(`clearcoatRoughnessFactor`, value); + this.shader.setDefine(`USE_CLEARCOAT`, true); + } + + public get clearcoatRoughnessFactor() { + return this.shader.getUniformFloat(`clearcoatRoughnessFactor`); + } + public set alphaCutoff(value: number) { this.shader.setUniform(`alphaCutoff`, value); } diff --git a/src/materials/SkyMaterial.ts b/src/materials/SkyMaterial.ts index 0bc7c7d5..f8f807fa 100644 --- a/src/materials/SkyMaterial.ts +++ b/src/materials/SkyMaterial.ts @@ -17,7 +17,7 @@ export class SkyMaterial extends Material { this.shader = new SkyShader(); this.shader.setUniformVector3(`eyesPos`, new Vector3()); this.shader.setUniformFloat(`exposure`, 1.0); - this.shader.setUniformFloat(`roughness`, 0.5); + this.shader.setUniformFloat(`roughness`, 0.0); } /** diff --git a/src/math/Color.ts b/src/math/Color.ts index db956d2d..8320908b 100644 --- a/src/math/Color.ts +++ b/src/math/Color.ts @@ -307,6 +307,22 @@ export class Color { return dst; } + /** + * lerp two color + * @param v + * @param c1 + * @param c2 + * @param target + * @returns + */ + public static lerp(v:number, c1:Color,c2:Color,target?:Color){ + let ret = target ? target : new Color(); + ret.r = (c2.r - c1.r) * v + c1.r ; + ret.g = (c2.g - c1.g) * v + c1.g ; + ret.b = (c2.b - c1.b) * v + c1.b ; + ret.a = (c2.a - c1.a) * v + c1.a ; + return target ; + } public static PRIMARY = 0x3f51b5; // diff --git a/src/math/UV.ts b/src/math/UV.ts index 06de89c0..5bbac7eb 100644 --- a/src/math/UV.ts +++ b/src/math/UV.ts @@ -1,3 +1,4 @@ +import { Vector4 } from '..'; import { Vector2 } from './Vector2'; /*** @@ -20,4 +21,12 @@ export class UV extends Vector2 { public length(): number { return 0; } + + public static getUVSheet(frame: number, countX: number, countY: number) { + let f = Math.floor(frame % (countX * countY)); + let fx = Math.floor(f / countX); + let fy = f % countX; + return new Vector4((fx / countX), (fy / countY), 1 / countX, 1 / countY); + } } + diff --git a/src/textures/BitmapTexture2DArray.ts b/src/textures/BitmapTexture2DArray.ts index a07c316c..f6897ae9 100644 --- a/src/textures/BitmapTexture2DArray.ts +++ b/src/textures/BitmapTexture2DArray.ts @@ -49,7 +49,7 @@ export class BitmapTexture2DArray extends Texture implements ITexture { */ public addTexture(bitmapTexture: BitmapTexture2D) { if (bitmapTexture.width != this.width || bitmapTexture.height != this.height) { - console.error("bitmap texture muse match bitmapTextureArray size!"); + console.error("bitmap texture must match bitmapTextureArray size!"); } // if (this._bitmapTextures.indexOf(bitmapTexture) == -1) { bitmapTexture.pid = this._bitmapTextures.length;