import { Laya } from "Laya" ; import { Camera , CameraEventFlags } from "laya/d3/core/Camera" ; import { DirectionLight } from "laya/d3/core/light/DirectionLight" ; import { CommandBuffer } from "laya/d3/core/render/command/CommandBuffer" ; import { DrawMeshInstancedCMD } from "laya/d3/core/render/command/DrawMeshInstancedCMD" ; import { InstanceLocation , MaterialInstancePropertyBlock } from "laya/d3/core/render/command/MaterialInstancePropertyBlock" ; import { Scene3D } from "laya/d3/core/scene/Scene3D" ; import { Matrix4x4 } from "laya/d3/math/Matrix4x4" ; import { Quaternion } from "laya/d3/math/Quaternion" ; import { Vector3 } from "laya/d3/math/Vector3" ; import { Vector4 } from "laya/d3/math/Vector4" ; import { PrimitiveMesh } from "laya/d3/resource/models/PrimitiveMesh" ; import { Shader3D } from "laya/d3/shader/Shader3D" ; import { Stage } from "laya/display/Stage" ; import { Button } from "laya/ui/Button" ; import { Browser } from "laya/utils/Browser" ; import { Handler } from "laya/utils/Handler" ; import { Stat } from "laya/utils/Stat" ; import { Laya3D } from "Laya3D" ; import { Event } from "laya/events/Event" ; import { CameraMoveScript } from "../common/CameraMoveScript" ; import { CustomInstanceMaterial } from "./DrawCustomInstanceDemo/CustomInstanceMaterial" ; import { Utils } from "laya/utils/Utils" ; import Client from "../../Client" ; export class CommandBuffer_DrawCustomInstance { mat : CustomInstanceMaterial ; instanceCMD : DrawMeshInstancedCMD ; materialBlock : MaterialInstancePropertyBlock ; matrixs : Matrix4x4 [ ] = [ ] ; matrixs1 : Matrix4x4 [ ] = [ ] ; colors : Vector4 [ ] = [ ] ; colors1 : Vector4 [ ] = [ ] ; currentColor : Vector4 [ ] = [ ] ; currentMatrix : Matrix4x4 [ ] = [ ] ; /**实例类型*/ private btype : any = "CommandBuffer_DrawCustomInstance" ; /**场景内按钮类型*/ private stype : any = 0 ; private changeActionButton : Button ; constructor ( ) { Laya3D . init ( 0 , 0 ) ; Stat . show ( ) ; Laya3D . init ( 100 , 100 ) ; Stat . show ( ) ; Shader3D . debugMode = true ; Laya . stage . scaleMode = Stage . SCALE_FULL ; Laya . stage . screenMode = Stage . SCREEN_NONE ; CustomInstanceMaterial . init ( ) ; let scene = ( < Scene3D > Laya . stage . addChild ( new Scene3D ( ) ) ) ; let camera = ( < Camera > scene . addChild ( new Camera ( 0 , 0.1 , 100 ) ) ) ; camera . transform . position = new Vector3 ( 14.85 , 17.08 , 35.89 ) ; camera . transform . rotation = new Quaternion ( 0 , 0 , 0 , 1 ) ; camera . addComponent ( CameraMoveScript ) ; camera . clearColor = new Vector4 ( 0.8 , 0.4 , 0.2 , 1.0 ) ; this . mat = new CustomInstanceMaterial ( ) ; let directionLight = ( < DirectionLight > scene . addChild ( new DirectionLight ( ) ) ) ; directionLight . color . setValue ( 1 , 1 , 1 ) ; let mat = directionLight . transform . worldMatrix ; mat . setForward ( new Vector3 ( - 1.0 , - 1.0 , - 1.0 ) ) ; directionLight . transform . worldMatrix = mat ; this . createCommandBuffer ( camera ) ; this . loadUI ( ) ; Laya . timer . frameLoop ( 1 , this , this . changetwoon ) ; } param camera createCommandBuffer ( camera ) { let buf = new CommandBuffer ( ) ; this . createMatrixArray ( ) ; this . materialBlock = new MaterialInstancePropertyBlock ( ) ; this . materialBlock . setVectorArray ( "a_InstanceColor" , this . colors1 , InstanceLocation . CUSTOME0 ) ; this . instanceCMD = buf . drawMeshInstance ( PrimitiveMesh . createSphere ( 0.5 ) , 0 , this . matrixs1 , this . mat , 0 , this . materialBlock , 900 ) ; camera . addCommandBuffer ( CameraEventFlags . BeforeTransparent , buf ) ; return ; } createMatrixArray ( ) { for ( let i = 0 ; i < 30 ; i ++ ) { for ( let j = 0 ; j < 30 ; j ++ ) { let ind = j * 30 + i ; if ( ind > 1023 ) break ; this . matrixs [ ind ] = new Matrix4x4 ( ) ; this . matrixs1 [ ind ] = new Matrix4x4 ( ) ; this . currentMatrix [ ind ] = new Matrix4x4 ( ) ; Matrix4x4 . createTranslate ( new Vector3 ( i , j , 0 ) , this . matrixs [ ind ] ) ; Matrix4x4 . createTranslate ( new Vector3 ( ind % 10 + 10 , Math . floor ( ind / 100 ) + 10 , Math . floor ( ind / 10 ) % 10 - 5 ) , this . matrixs1 [ ind ] ) ; this . colors [ ind ] = new Vector4 ( 1 - i / 30.0 , 1 - j / 30.0 , 1.0 , 1.0 ) ; this . colors1 [ ind ] = new Vector4 ( 1 - i / 30.0 , 1 - j / 30.0 , 0.0 , 1.0 ) ; this . currentColor [ ind ] = new Vector4 ( ) ; } } return null ; } changePositionColor ( sourceColor , sourceMatrix , destColor , destMatrix , lerp ) { var lep = lerp ; var invert = 1 - lerp ; for ( let i = 0 ; i < 30 ; i ++ ) { for ( let j = 0 ; j < 30 ; j ++ ) { let ind = j * 30 + i ; this . currentColor [ ind ] . setValue ( sourceColor [ ind ] . x * lep + destColor [ ind ] . x * invert , sourceColor [ ind ] . y * lep + destColor [ ind ] . y * invert , sourceColor [ ind ] . z * lep + destColor [ ind ] . z * invert , 1.0 ) ; var mat = this . currentMatrix [ ind ] . elements ; var sourcemat = sourceMatrix [ ind ] . elements ; var destmat = destMatrix [ ind ] . elements ; mat [ 12 ] = sourcemat [ 12 ] * lep + destmat [ 12 ] * invert ; mat [ 13 ] = sourcemat [ 13 ] * lep + destmat [ 13 ] * invert ; mat [ 14 ] = sourcemat [ 14 ] * lep + destmat [ 14 ] * invert ; } } } private timer = 0 ; private delta = 0.01 ; changetwoon ( ) { this . timer += this . delta ; if ( this . timer < 0 || this . timer > 1 ) { this . timer = Math . round ( this . timer ) ; return ; } this . changePositionColor ( this . colors , this . matrixs , this . colors1 , this . matrixs1 , this . timer ) ; this . instanceCMD . setWorldMatrix ( this . currentMatrix ) ; this . materialBlock . setVectorArray ( "a_InstanceColor" , this . currentColor , InstanceLocation . CUSTOME0 ) ; } private curStateIndex : number = 0 ; private loadUI ( ) { Laya . loader . load ( [ "res/threeDimen/ui/button.png" ] , Handler . create ( this , function ( ) : void { this . changeActionButton = Laya . stage . addChild ( new Button ( "res/threeDimen/ui/button.png" , "切换颜色位置1" ) ) ; this . changeActionButton . size ( 160 , 40 ) ; this . changeActionButton . labelBold = true ; this . changeActionButton . labelSize = 30 ; this . changeActionButton . sizeGrid = "4,4,4,4" ; this . changeActionButton . scale ( Browser . pixelRatio , Browser . pixelRatio ) ; this . changeActionButton . pos ( Laya . stage . width / 2 - this . changeActionButton . width * Browser . pixelRatio / 2 , Laya . stage . height - 100 * Browser . pixelRatio ) ; this . changeActionButton . on ( Event . CLICK , this , this . stypeFun0 ) ; } ) ) ; } stypeFun0 ( label = "颜色位置2" ) { if ( ++ this . curStateIndex % 2 == 1 ) { this . changeActionButton . label = "颜色位置1" ; this . delta = - 0.01 ; } else { this . changeActionButton . label = "颜色位置2" ; this . delta = 0.01 ; } label = this . changeActionButton . label ; Client . instance . send ( { type : "next" , btype : this . btype , stype : 0 , value : label } ) ; } }