• Content count

  • Joined

  • Last visited

About BlackMojito

  • Rank
    Advanced Member
  • Birthday 03/23/1987

Profile Information

  • Gender
  • Location
  1. About linearity and gamma correction

    Yeah but it is quite weird though as there is no "pow 2.2" in the StandardMaterial's shader either. Where is the correction done then?
  2. Hi All, I've looked into the source code of Texture and I did not find any code which allowed loading texture directly in sRGB. I could not find them in the default.fragment.fx either something which handled the linearity. The only thing I've seen was converting the output to linear space if applying image processing afterwards. Another question is that do we have a built-in gamma correction effect? I know it's simple to implement but I'd rather use the built-in one if existing BTW, should I still apply the gamma correction if I apply tone mapping before it? I am not familiar with the tone mappers and not sure if gamma correction has already been baked in them...
  3. Just as the screenshot shows, I have SSAO on the skybox too. How I can remove this? How can I disable depth writing when rendering the box? Thanks a lot
  4. SSAO sucks with Scene.UseRightHandedSystem

    I am sorry I just saw your reply. Luckily you guys have already fixed the bug. Thanks you so much. That's really cool!
  5. Hi Folks, I tried to integrate the SSAO pipeline with as shown in this sample However the result was not correct if I set the scene to using right hand system. The occlusion result does not follow the camera move. I think should be a calculation error linked either to the projection matrix or to the view matrix. I really think that it is a serious bug. I don't want to change my whole application to left hand system Thanks
  6. Deferred Normal-Depth buffer

    OK I realized that the official example SSAO2 worked now and it used MultiRenderTarget...
  7. Deferred Normal-Depth buffer

    Hi Folks, I am working my own scalable ambient occlusion effect and I do need a render pass which generate a normal-depth buffer. And then I compose a post process pipeline which does the normal SAO + Blur + Composing stuff but it seems that the current architecture does not allow me to insert a pass between the "original color" pass and the PostProcessRenderPipeline. I know that I can reconstruct the normal from the depth buffer but it seems that I am going to have some artifacts which cannot be avoided. So how can I do that? BTW, it seems that Babylon now support multi-RenderTargets. It is true, I would like to write my own shader which writes to my Normal-Depth buffer during the color pass. Is it possible now? Where can I find some samples about MRT? Thanks
  8. SSAO quality bug?

    Please see the attached screenshots. It is from the sample on the official site. Is it a bug in the blur shader?
  9. Hi Folks, I am still a little bit confused with the Rendering pipeline system. Are the SSAORenderingPipeline, DefaultRenderingPipeline and StandardRenderingPipeline just for convenience? So we can use only one of them at a time? If I would like to combine some effects in the Default with SSAO, basically I need to write my own RenderingPipeline, right? Thanks in advance
  10. Autodesk Forge like camera rotation

    Below is my small class. I still don't know what is missing. The basic idea is that the somehow like what the image below illustrates. a is the pivot and b is the target... import * as BABYLON from 'babylonjs' import * as MathUtils from '../../Utils/MathUtils' export class ArcRotatePivotCamera extends BABYLON.ArcRotateCamera { private _pivot: BABYLON.Vector3 | null; private _oldAlpha: number; private _oldBeta: number; private _pivotToEyeDistance: number = 0; constructor(name: string, alpha: number, beta: number, radius: number, target: BABYLON.Vector3, scene: BABYLON.Scene) { super(name, alpha, beta, radius, target, scene); this._oldAlpha = alpha; this._oldBeta = beta; this._pivotToEyeDistance = radius; } get pivot(): BABYLON.Vector3 | null { return this._pivot; } set pivot(pivot: BABYLON.Vector3 | null) { this._pivot = pivot; } private updatePivotToEyeDistance(): void { let pivotToTargetLengthSquared = this._getTargetPosition().subtract(this._pivot).lengthSquared(); this._pivotToEyeDistance = Math.sqrt(pivotToTargetLengthSquared + this.radius * this.radius); } private updateAlphaBeta(): void { let diff: BABYLON.Vector3 = this._newPosition.subtract(this._pivot); this.beta = Math.acos(diff.z / this._pivotToEyeDistance); this.alpha = Math.atan2(diff.y, diff.x); } _checkInputs(): void { this._oldAlpha = this.alpha; this._oldBeta = this.beta; //if (async) collision inspection was triggered, don't update the camera's position - until the collision callback was called. if (this._collisionTriggered) { return; } this.inputs.checkInputs(); // Zoom Inertia if (this.inertialRadiusOffset !== 0) { this.radius -= this.inertialRadiusOffset; let viewDir = this._target.subtract(this._newPosition).normalize(); this._newPosition.addInPlace(viewDir.scaleInPlace(this.inertialRadiusOffset)); this.updatePivotToEyeDistance(); this.updateAlphaBeta(); this.inertialRadiusOffset *= this.inertia; if (Math.abs(this.inertialRadiusOffset) < this.speed * BABYLON.Epsilon) this.inertialRadiusOffset = 0; } // Rotation Inertia if (this.inertialAlphaOffset !== 0 || this.inertialBetaOffset !== 0) { if (this.getScene().useRightHandedSystem) { this.alpha -= this.beta <= 0 ? -this.inertialAlphaOffset : this.inertialAlphaOffset; } else { this.alpha += this.beta <= 0 ? -this.inertialAlphaOffset : this.inertialAlphaOffset; } this.beta += this.inertialBetaOffset; this.inertialAlphaOffset *= this.inertia; this.inertialBetaOffset *= this.inertia; if (Math.abs(this.inertialAlphaOffset) < BABYLON.Epsilon) this.inertialAlphaOffset = 0; if (Math.abs(this.inertialBetaOffset) < BABYLON.Epsilon) this.inertialBetaOffset = 0; } // Panning inertia if (this.inertialPanningX !== 0 || this.inertialPanningY !== 0) { if (!this._localDirection) { this._localDirection = BABYLON.Vector3.Zero(); this._transformedDirection = BABYLON.Vector3.Zero(); } this._localDirection.copyFromFloats(this.inertialPanningX, this.inertialPanningY, this.inertialPanningY); this._localDirection.multiplyInPlace(this.panningAxis); this._viewMatrix.invertToRef(this._cameraTransformMatrix); BABYLON.Vector3.TransformNormalToRef(this._localDirection, this._cameraTransformMatrix, this._transformedDirection); //Eliminate y if map panning is enabled (panningAxis == 1,0,1) if (!this.panningAxis.y) { this._transformedDirection.y = 0; } if (!this._targetHost) { if (this.panningDistanceLimit) { this._transformedDirection.addInPlace(this._target); var distanceSquared = BABYLON.Vector3.DistanceSquared(this._transformedDirection, this.panningOriginTarget); if (distanceSquared <= (this.panningDistanceLimit * this.panningDistanceLimit)) { let oldTarget =; this._target.copyFrom(this._transformedDirection); let diff = this._target.subtract(oldTarget); this._newPosition.addInPlace(diff); } } else { this._target.addInPlace(this._transformedDirection); this._newPosition.addInPlace(this._transformedDirection); } } this.updatePivotToEyeDistance(); this.updateAlphaBeta(); this.inertialPanningX *= this.panningInertia; this.inertialPanningY *= this.panningInertia; if (Math.abs(this.inertialPanningX) < this.speed * BABYLON.Epsilon) this.inertialPanningX = 0; if (Math.abs(this.inertialPanningY) < this.speed * BABYLON.Epsilon) this.inertialPanningY = 0; } // Limits this._checkLimits(); this.onAfterCheckInputsObservable.notifyObservers(this); } _getViewMatrix(): BABYLON.Matrix { // Compute let cosa = Math.cos(this.alpha); let sina = Math.sin(this.alpha); let cosb = Math.cos(this.beta); let sinb = Math.sin(this.beta); if (sinb === 0) { sinb = 0.0001; } let target = this._getTargetPosition(); let rotateEnd = new BABYLON.Vector3(cosa * sinb, cosb, sina * sinb); let trackballVector = rotateEnd.scale(this.radius); let rotationMatrix: BABYLON.Matrix = null; if (this._pivot) { let cosaOld = Math.cos(this._oldAlpha); let sinaOld = Math.sin(this._oldAlpha); let cosbOld = Math.cos(this._oldBeta); let sinbOld = Math.sin(this._oldBeta); if (sinbOld === 0) { sinbOld = 0.0001; } let pivotToEye = this._newPosition.subtract(this._pivot); let targetToEye = this._newPosition.subtract(this._pivot); let targetDist = targetToEye.length(); targetToEye.normalize(); let rotateStart = new BABYLON.Vector3(cosaOld * sinbOld, cosbOld, sinaOld * sinbOld); let transform = MathUtils.rotationMatrixBetweenVectors(rotateStart, rotateEnd); pivotToEye = BABYLON.Vector3.TransformNormal(pivotToEye, transform); targetToEye = BABYLON.Vector3.TransformNormal(targetToEye, transform); this._newPosition = this._pivot.add(pivotToEye); target = this._newPosition.subtract(targetToEye.scale(targetDist)); } if (this.getScene().collisionsEnabled && this.checkCollisions) { if (!this._collider) { this._collider = new BABYLON.Collider(); } this._collider.radius = this.collisionRadius; this._newPosition.subtractToRef(this.position, this._collisionVelocity); this._collisionTriggered = true; this.getScene().collisionCoordinator.getNewPosition(this.position, this._collisionVelocity, this._collider, 3, null, this._onCollisionPositionChange, this.uniqueId); } else { this.position.copyFrom(this._newPosition); let up = this.upVector; if (this.allowUpsideDown && sinb < 0) { up = up.clone(); up = up.negate(); } if (this.getScene().useRightHandedSystem) { BABYLON.Matrix.LookAtRHToRef(this.position, target, up, this._viewMatrix); } else { BABYLON.Matrix.LookAtLHToRef(this.position, target, up, this._viewMatrix); } this._viewMatrix.m[12] += this.targetScreenOffset.x; this._viewMatrix.m[13] += this.targetScreenOffset.y; } this._currentTarget = target; return this._viewMatrix; } }
  11. Autodesk Forge like camera rotation

    No, I am pretty sure that they are modifying the view matrix instead of using your approach. In Autodesk Fusion 360, they have the same camera stuff. I know that it is a camera with a pivot, but I just don't know how to calculate the view matrix.
  12. Autodesk Forge like camera rotation

    Basically, the problem of the existing ArcRotateCamera is that when the object is not at the center of the viewport, the rotation is not correct because the camera always rotates around its target.
  13. Autodesk Forge like camera rotation

    Hi RaananW, If you click this link, you can see that there are models that we can play with (rotate, pan, zoom). Obviously the camera rotates around a pivot which I guess is the center of the model's bounding sphere. I tried to customize ArcRotateCamera but it still cannot work like theirs. Could you please provide me some ideas? Thanks
  14. Hi Folks, What is the recommended way to import the content of an OBJ/STL into an existing scene? I need the meshes and the materials as well. Below are the three ways I found in the official tutorials. I think that the first one cannot be used in my case as it creates a new scene. So besides the first one, what is the difference between the second one and third one? Can they import the associated materials as well? BABYLON.SceneLoader.Load("/assets/", "batman.obj", engine, function (newScene) { // ... }); var loader = new BABYLON.AssetsManager(scene); var batman = loader.addMeshTask("batman", "", "assets/", "batman.obj"); BABYLON.SceneLoader.ImportMesh("batmanface", "batman.obj", scene, function (meshes) { // ... });
  15. Hi NasimiAsl, I was told that you are the author of CustomMaterial. I really want to customize a little bit PBR materials so that I can set multiple clip planes. Could you please share me some of your experience? So far I have no idea how to do that.