import { CompareFunction, CullMode, Engine, Material, Shader, TextureCube, Vector4 } from "oasis-engine"; export class ARSkyMaterial extends Material { constructor(engine: Engine) { const vertexSource = ` attribute vec3 POSITION; uniform mat4 u_mvpNoscale; varying vec3 v_cubeUV; void main() { v_cubeUV = vec3(-POSITION.x, POSITION.y, POSITION.z ); gl_Position = u_mvpNoscale * vec4( POSITION, 1.0 ); gl_Position.z = gl_Position.w; } `; const fragSource = ` uniform samplerCube u_cube; varying vec3 v_cubeUV; uniform vec4 u_cubeDecodeParam; vec4 RGBMToLinear(vec4 value, float maxRange ) { return vec4( value.rgb * value.a * maxRange, 1.0 ); } vec4 linearToGamma(vec4 linearIn){ return vec4( pow(linearIn.rgb, vec3(1.0 / 2.2)), linearIn.a); } void main (void) { vec4 textureColor = textureCube( u_cube, v_cubeUV ); if (u_cubeDecodeParam.x > 0.0){ textureColor = RGBMToLinear(textureColor, u_cubeDecodeParam.y); textureColor = linearToGamma(textureColor); } gl_FragColor = textureColor; } `; const shader = Shader.create("ARSkyMaterial", vertexSource, fragSource); super(engine, shader); this.renderState.rasterState.cullMode = CullMode.Off; this.renderState.depthState.compareFunction = CompareFunction.LessEqual; this.shaderData.setVector4("u_cubeDecodeParam", this._decodeParam); } private _decodeParam: Vector4 = new Vector4(0, 5, 0, 0); /** * Whether to decode from texture with RGBM format. */ get textureDecodeRGBM(): boolean { return Boolean(this._decodeParam.x); } set textureDecodeRGBM(value: boolean) { this._decodeParam.x = Number(value); } /** * RGBM decode factor, default 5.0. */ get RGBMDecodeFactor(): number { return this._decodeParam.y; } set RGBMDecodeFactor(value: number) { this._decodeParam.y = value; } /** * Texture cube map of the sky box material. */ get textureCubeMap(): TextureCube { return this.shaderData.getTexture("u_cube") as TextureCube; } set textureCubeMap(v: TextureCube) { this.shaderData.setTexture("u_cube", v); } }