Skip to content

Commit

Permalink
Refactor skybox using infinity matrix (#1048)
Browse files Browse the repository at this point in the history
* feat: refactor skybox using infinity matrix

* fix: camera orth sky render error
  • Loading branch information
yangfengzzz authored Sep 20, 2022
1 parent 6e127ce commit 6b8b696
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 47 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/Camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ class MathTemp {
*/
@dependentComponents(Transform)
export class Camera extends Component {
/** @internal */
static _vpMatrixProperty = Shader.getPropertyByName("u_VPMat");

private static _viewMatrixProperty = Shader.getPropertyByName("u_viewMat");
private static _projectionMatrixProperty = Shader.getPropertyByName("u_projMat");
private static _vpMatrixProperty = Shader.getPropertyByName("u_VPMat");
private static _inverseViewMatrixProperty = Shader.getPropertyByName("u_viewInvMat");
private static _inverseProjectionMatrixProperty = Shader.getPropertyByName("u_projInvMat");
private static _cameraPositionProperty = Shader.getPropertyByName("u_cameraPos");
Expand Down
40 changes: 2 additions & 38 deletions packages/core/src/RenderPipeline/BasicRenderPipeline.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Matrix, Vector2, Vector3 } from "@oasis-engine/math";
import { Vector2, Vector3 } from "@oasis-engine/math";
import { SpriteMask } from "../2d";
import { Background } from "../Background";
import { Logger } from "../base";
import { Camera } from "../Camera";
import { DisorderedArray } from "../DisorderedArray";
import { Engine } from "../Engine";
Expand All @@ -15,7 +14,6 @@ import { Shader } from "../shader/Shader";
import { ShaderMacroCollection } from "../shader/ShaderMacroCollection";
import { CascadedShadowCasterPass } from "../shadow/CascadedShadowCasterPass";
import { ShadowMode } from "../shadow/enum/ShadowMode";
import { Sky } from "../sky";
import { RenderTarget, TextureCubeFace } from "../texture";
import { RenderContext } from "./RenderContext";
import { RenderElement } from "./RenderElement";
Expand Down Expand Up @@ -190,7 +188,7 @@ export class BasicRenderPipeline {
this._alphaTestQueue.render(camera, pass.replaceMaterial, pass.mask);
if (camera.clearFlags & CameraClearFlags.Color) {
if (background.mode === BackgroundMode.Sky) {
this._drawSky(engine, camera, background.sky);
background.sky._render(camera);
} else if (background.mode === BackgroundMode.Texture && background.texture) {
this._drawBackgroundTexture(engine, background);
}
Expand Down Expand Up @@ -245,40 +243,6 @@ export class BasicRenderPipeline {
rhi.drawPrimitive(mesh, mesh.subMesh, program);
}

private _drawSky(engine: Engine, camera: Camera, sky: Sky): void {
const { material, mesh, _matrix } = sky;
if (!material) {
Logger.warn("The material of sky is not defined.");
return;
}
if (!mesh) {
Logger.warn("The mesh of sky is not defined.");
return;
}

const rhi = engine._hardwareRenderer;
const { shaderData, shader, renderState } = material;

const compileMacros = Shader._compileMacros;
ShaderMacroCollection.unionCollection(camera._globalShaderMacro, shaderData._macroCollection, compileMacros);

const { viewMatrix, projectionMatrix } = camera;
_matrix.copyFrom(viewMatrix);
const e = _matrix.elements;
e[12] = e[13] = e[14] = 0;
Matrix.multiply(projectionMatrix, _matrix, _matrix);
shaderData.setMatrix("u_mvpNoscale", _matrix);

const program = shader.passes[0]._getShaderProgram(engine, compileMacros);
program.bind();
program.groupingOtherUniformBlock();
program.uploadAll(program.materialUniformBlock, shaderData);
program.uploadUnGroupTextures();

renderState._apply(engine, false);
rhi.drawPrimitive(mesh, mesh.subMesh, program);
}

private _callRender(context: RenderContext): void {
const renderers = this._camera.engine._componentsManager._renderers;
const camera = context._camera;
Expand Down
7 changes: 3 additions & 4 deletions packages/core/src/shaderlib/extra/skybox.vs.glsl
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
#include <common_vert>

uniform mat4 u_mvpNoscale;
uniform mat4 u_VPMat;

varying vec3 v_cubeUV;

void main() {

v_cubeUV = vec3( -POSITION.x, POSITION.yz );// TextureCube is left-hand,so x need inverse
gl_Position = u_mvpNoscale * vec4( POSITION, 1.0 );
gl_Position.z = gl_Position.w;
gl_Position = u_VPMat * vec4( POSITION, 1.0 );

}
}
66 changes: 62 additions & 4 deletions packages/core/src/sky/Sky.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,73 @@
import { Matrix } from "@oasis-engine/math";
import { Mesh } from "../graphic";
import { MathUtil, Matrix } from "@oasis-engine/math";
import { Mesh } from "../graphic/Mesh";
import { Material } from "../material";
import { Camera } from "../Camera";
import { Logger } from "../base/Logger";
import { Shader } from "../shader/Shader";
import { ShaderMacroCollection } from "../shader/ShaderMacroCollection";

/**
* Sky.
*/
export class Sky {
private static _epsilon: number = 1e-6;
private static _viewProjMatrix: Matrix = new Matrix();
private static _projectionMatrix: Matrix = new Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, Sky._epsilon - 1, -1, 0, 0, 0, 0);

/** Material of the sky. */
material: Material;
/** Mesh of the sky. */
mesh: Mesh;
/** @internal */
_matrix: Matrix = new Matrix();

/**
* @internal
*/
_render(camera: Camera): void {
const { material, mesh } = this;
if (!material) {
Logger.warn("The material of sky is not defined.");
return;
}
if (!mesh) {
Logger.warn("The mesh of sky is not defined.");
return;
}

const { engine, aspectRatio, fieldOfView, viewMatrix, shaderData: cameraShaderData } = camera;
const { _viewProjMatrix: viewProjMatrix, _projectionMatrix: projectionMatrix } = Sky;
const rhi = engine._hardwareRenderer;
const { shaderData: materialShaderData, shader, renderState } = material;

// no-scale view matrix
viewProjMatrix.copyFrom(viewMatrix);
const e = viewProjMatrix.elements;
e[12] = e[13] = e[14] = 0;

// epsilon-infinity projection matrix http://terathon.com/gdc07_lengyel.pdf
const f = 1.0 / Math.tan(MathUtil.degreeToRadian(fieldOfView) / 2);
projectionMatrix.elements[0] = f / aspectRatio;
projectionMatrix.elements[5] = f;

// view-proj matrix
Matrix.multiply(projectionMatrix, viewProjMatrix, viewProjMatrix);
const originViewProjMatrix = cameraShaderData.getMatrix(Camera._vpMatrixProperty);
cameraShaderData.setMatrix(Camera._vpMatrixProperty, viewProjMatrix);

const compileMacros = Shader._compileMacros;
ShaderMacroCollection.unionCollection(
camera._globalShaderMacro,
materialShaderData._macroCollection,
compileMacros
);
const program = shader.passes[0]._getShaderProgram(engine, compileMacros);
program.bind();
program.groupingOtherUniformBlock();
program.uploadAll(program.cameraUniformBlock, cameraShaderData);
program.uploadAll(program.materialUniformBlock, materialShaderData);
program.uploadUnGroupTextures();

renderState._apply(engine, false);
rhi.drawPrimitive(mesh, mesh.subMesh, program);
cameraShaderData.setMatrix(Camera._vpMatrixProperty, originViewProjMatrix);
}
}

0 comments on commit 6b8b696

Please sign in to comment.