Skip to content

Commit

Permalink
Add dof (cocos#17798)
Browse files Browse the repository at this point in the history
  • Loading branch information
GengineJS authored Nov 6, 2024
1 parent 0e62436 commit 95afe55
Show file tree
Hide file tree
Showing 7 changed files with 431 additions and 603 deletions.
10 changes: 10 additions & 0 deletions cocos/render-scene/scene/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,14 @@ export class Camera {
return this._matView$;
}

/**
* @en The inverse of the view matrix of the camera
* @zh 相机的逆视图矩阵
*/
get matViewInv (): Mat4 {
return this._matViewInv$;
}

/**
* @en The projection matrix of the camera
* @zh 相机的投影矩阵
Expand Down Expand Up @@ -835,6 +843,7 @@ export class Camera {
private _curTransform$ = SurfaceTransform.IDENTITY;
private _isProjDirty$ = true;
private _matView$: Mat4 = mat4();
private _matViewInv$: Mat4 = mat4();
private _matProj$: Mat4 = mat4();
private _matProjInv$: Mat4 = mat4();
private _matViewProj$: Mat4 = mat4();
Expand Down Expand Up @@ -1021,6 +1030,7 @@ export class Camera {
this._forward$.z = -this._matView$.m10;
// Remove scale
Mat4.multiply(this._matView$, new Mat4().scale(this._node$.worldScale), this._matView$);
Mat4.invert(this._matViewInv$, this._matView$);
this._node$.getWorldPosition(this._position$);
viewProjDirty = true;
}
Expand Down
65 changes: 47 additions & 18 deletions editor/assets/default_renderpipeline/builtin-pipeline-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
Material,
rendering,
Texture2D,
Vec3,
} from 'cc';

import { EDITOR } from 'cc/env';
Expand Down Expand Up @@ -179,7 +180,7 @@ export class BuiltinPipelineSettings extends Component {
@property({
group: { id: 'DepthOfField', name: 'DepthOfField (PostProcessing)', style: 'section' },
type: CCBoolean,
visible: false,
visible: true,
})
set dofEnable(value: boolean) {
this._settings.depthOfField.enabled = value;
Expand All @@ -194,7 +195,7 @@ export class BuiltinPipelineSettings extends Component {
@property({
group: { id: 'DepthOfField', name: 'DepthOfField (PostProcessing)', style: 'section' },
type: Material,
visible: false,
visible: true,
})
set dofMaterial(value: Material) {
if (this._settings.depthOfField.material === value) {
Expand All @@ -213,41 +214,69 @@ export class BuiltinPipelineSettings extends Component {
group: { id: 'DepthOfField', name: 'DepthOfField (PostProcessing)', style: 'section' },
type: CCFloat,
min: 0,
visible: false,
visible: true,
})
set dofFocusDistance(value: number) {
this._settings.depthOfField.focusDistance = value;
set dofMinRange(value: number) {
this._settings.depthOfField.minRange = value;
}
get dofFocusDistance(): number {
return this._settings.depthOfField.focusDistance;
get dofMinRange(): number {
return this._settings.depthOfField.minRange;
}

@property({
group: { id: 'DepthOfField', name: 'DepthOfField (PostProcessing)', style: 'section' },
type: CCFloat,
min: 0,
visible: false,
visible: true,
})
set dofFocusRange(value: number) {
this._settings.depthOfField.focusRange = value;
set dofMaxRange(value: number) {
this._settings.depthOfField.maxRange = value;
}
get dofFocusRange(): number {
return this._settings.depthOfField.focusRange;
get dofMaxRange(): number {
return this._settings.depthOfField.maxRange;
}

@property({
group: { id: 'DepthOfField', name: 'DepthOfField (PostProcessing)', style: 'section' },
type: CCFloat,
min: 0,
max: 1,
visible: true,
})
set dofIntensity(value: number) {
this._settings.depthOfField.intensity = value;
}
get dofIntensity(): number {
return this._settings.depthOfField.intensity;
}


@type(CCFloat)
@property({
group: { id: 'DepthOfField', name: 'DepthOfField (PostProcessing)', style: 'section' },
type: CCFloat,
range: [1, 10, 0.01],
range: [0.01, 10, 0.01],
slide: true,
visible: false,
visible: true,
})
set dofBlurRadius(value: number) {
this._settings.depthOfField.blurRadius = value;
}
get dofBlurRadius(): number {
return this._settings.depthOfField.blurRadius;
}

@type(Vec3)
@property({
group: { id: 'DepthOfField', name: 'DepthOfField (PostProcessing)', style: 'section' },
type: Vec3,
visible: true,
})
set dofBokehRadius(value: number) {
this._settings.depthOfField.bokehRadius = value;
set dofFocusPos(value: Vec3) {
this._settings.depthOfField.focusPos = value;
}
get dofBokehRadius(): number {
return this._settings.depthOfField.bokehRadius;
get dofFocusPos(): Vec3 {
return this._settings.depthOfField.focusPos;
}

// Bloom
Expand Down
33 changes: 20 additions & 13 deletions editor/assets/default_renderpipeline/builtin-pipeline-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* ========================= !DO NOT CHANGE THE FOLLOWING SECTION MANUALLY! =========================
*/
/* eslint-disable max-len */
import { Material, Texture2D, gfx } from 'cc';
import { Material, Texture2D, gfx, Vec3 } from 'cc';

const { SampleCount } = gfx;

Expand Down Expand Up @@ -99,19 +99,23 @@ export function fillRequiredHBAO(value: HBAO): void {
export interface DepthOfField {
enabled: boolean; /* false */
/* refcount */ material: Material | null;
focusDistance: number; /* 0 */
focusRange: number; /* 0 */
bokehRadius: number; /* 1 */
minRange: number; /* 0 */
maxRange: number; /* 0 */
blurRadius: number; /* 1 */
intensity: number;
focusPos: Vec3;
[name: string]: unknown;
}

export function makeDepthOfField(): DepthOfField {
return {
enabled: false,
material: null,
focusDistance: 0,
focusRange: 0,
bokehRadius: 1,
minRange: 0,
maxRange: 50,
blurRadius: 1,
intensity: 0.2,
focusPos: new Vec3(0, 0, 0),
};
}

Expand All @@ -122,14 +126,17 @@ export function fillRequiredDepthOfField(value: DepthOfField): void {
if (value.material === undefined) {
value.material = null;
}
if (value.focusDistance === undefined) {
value.focusDistance = 0;
if (value.minRange === undefined) {
value.minRange = 0;
}
if (value.focusRange === undefined) {
value.focusRange = 0;
if (value.maxRange === undefined) {
value.maxRange = 0;
}
if (value.bokehRadius === undefined) {
value.bokehRadius = 1;
if (value.blurRadius === undefined) {
value.blurRadius = 1;
}
if (value.focusPos === undefined) {
value.focusPos = new Vec3();
}
}

Expand Down
90 changes: 29 additions & 61 deletions editor/assets/default_renderpipeline/builtin-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ if (rendering) {
private readonly _cameraConfigs = new CameraConfigs();
// DepthOfField
private readonly _cocParams = new Vec4(0, 0, 0, 0);
private readonly _focusPos = new Vec4(0, 0, 0, 1);
private readonly _cocTexSize = new Vec4(0, 0, 0, 0);
// Bloom
private readonly _bloomParams = new Vec4(0, 0, 0, 0);
Expand Down Expand Up @@ -1031,77 +1032,44 @@ if (rendering) {
): void {
// https://catlikecoding.com/unity/tutorials/advanced-rendering/depth-of-field/

this._cocParams.x = settings.depthOfField.focusDistance;
this._cocParams.y = settings.depthOfField.focusRange;
this._cocParams.z = settings.depthOfField.bokehRadius;
this._cocParams.w = 0.0;
this._cocParams.x = settings.depthOfField.minRange;
this._cocParams.y = settings.depthOfField.maxRange;// camera.farClip;// settings.depthOfField.focusRange;
this._cocParams.z = settings.depthOfField.blurRadius;
this._cocParams.w = settings.depthOfField.intensity;
this._focusPos.x = settings.depthOfField.focusPos.x;
this._focusPos.y = settings.depthOfField.focusPos.y;
this._focusPos.z = settings.depthOfField.focusPos.z;
this._cocTexSize.x = 1.0 / width;
this._cocTexSize.y = 1.0 / height;
this._cocTexSize.z = width;
this._cocTexSize.w = height;

const halfWidth = Math.max(Math.floor(width / 2), 1);
const halfHeight = Math.max(Math.floor(height / 2), 1);

const cocName = ldrColorName;
const prefilterName = `DofPrefilter${id}`;
const bokehName = `DofBokeh${id}`;
const filterName = `DofFilter${id}`;

// CoC
const blurName = ldrColorName;

// Blur Pass
const blurPass = ppl.addRenderPass(width, height, 'cc-dof-blur');
blurPass.addRenderTarget(blurName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
blurPass.addTexture(dofRadianceName, 'screenTex');
blurPass.setVec4('g_platform', this._configs.platform);
blurPass.setVec4('blurParams', this._cocParams);
blurPass.setVec4('mainTexTexelSize', this._cocTexSize);
blurPass
.addQueue(QueueHint.OPAQUE)
.addCameraQuad(camera, dofMaterial, 0); // addCameraQuad will set camera related UBOs
// coc pass
const cocPass = ppl.addRenderPass(width, height, 'cc-dof-coc');
cocPass.addRenderTarget(cocName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
cocPass.addTexture(depthStencil, 'DepthTex');
cocPass.addRenderTarget(radianceName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
cocPass.addTexture(blurName, 'colorTex');
cocPass.addTexture(depthStencil, "DepthTex");
cocPass.addTexture(dofRadianceName, "screenTex");
cocPass.setVec4('g_platform', this._configs.platform);
cocPass.setMat4('proj', camera.matProj);
cocPass.setMat4('invProj', camera.matProjInv);
cocPass.setMat4('viewMatInv', camera.matViewInv);
cocPass.setVec4('cocParams', this._cocParams);
cocPass.setVec4('focus', this._focusPos);
cocPass
.addQueue(QueueHint.OPAQUE)
.addCameraQuad(camera, dofMaterial, 0); // addCameraQuad will set camera related UBOs

// Downsample and Prefilter
const prefilterPass = ppl.addRenderPass(halfWidth, halfHeight, 'cc-dof-prefilter');
prefilterPass.addRenderTarget(prefilterName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
prefilterPass.addTexture(dofRadianceName, 'colorTex');
prefilterPass.addTexture(cocName, 'cocTex');
prefilterPass.setVec4('g_platform', this._configs.platform);
prefilterPass.setVec4('mainTexTexelSize', this._cocTexSize);
prefilterPass
.addQueue(QueueHint.OPAQUE)
.addFullscreenQuad(dofMaterial, 1);

// Bokeh blur
const bokehPass = ppl.addRenderPass(halfWidth, halfHeight, 'cc-dof-bokeh');
bokehPass.addRenderTarget(bokehName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
bokehPass.addTexture(prefilterName, 'prefilterTex');
bokehPass.setVec4('g_platform', this._configs.platform);
bokehPass.setVec4('mainTexTexelSize', this._cocTexSize);
bokehPass.setVec4('cocParams', this._cocParams);
bokehPass
.addQueue(QueueHint.OPAQUE)
.addFullscreenQuad(dofMaterial, 2);

// Filtering
const filterPass = ppl.addRenderPass(halfWidth, halfHeight, 'cc-dof-filter');
filterPass.addRenderTarget(filterName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
filterPass.addTexture(bokehName, 'bokehTex');
filterPass.setVec4('g_platform', this._configs.platform);
filterPass.setVec4('mainTexTexelSize', this._cocTexSize);
filterPass
.addQueue(QueueHint.OPAQUE)
.addFullscreenQuad(dofMaterial, 3);

// Combine
const combinePass = ppl.addRenderPass(width, height, 'cc-dof-combine');
combinePass.addRenderTarget(radianceName, LoadOp.CLEAR, StoreOp.STORE, this._clearColorTransparentBlack);
combinePass.addTexture(dofRadianceName, 'colorTex');
combinePass.addTexture(cocName, 'cocTex');
combinePass.addTexture(filterName, 'filterTex');
combinePass.setVec4('g_platform', this._configs.platform);
combinePass.setVec4('cocParams', this._cocParams);
combinePass
.addQueue(QueueHint.OPAQUE)
.addFullscreenQuad(dofMaterial, 4);
.addCameraQuad(camera, dofMaterial, 1);
}

private _addKawaseDualFilterBloomPasses(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

#pragma rate DepthTex pass
uniform sampler2D DepthTex; //Sample_Point_Clamp
float GetDepthFromTex(vec2 uv) {
return texture(DepthTex, saturate(uv)).r;
}

float GetLinearDepthWithProj(vec2 uv, mat4 proj) {
float depthHS = texture(DepthTex, saturate(uv)).r * 2.0 - 1.0; // -1.0 ~ +1.0
float depthHS = GetDepthFromTex(uv) * 2.0 - 1.0; // -1.0 ~ +1.0
return -GetCameraDepthRH(depthHS, proj);
}
Loading

0 comments on commit 95afe55

Please sign in to comment.