Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dof #17798

Merged
merged 2 commits into from
Nov 6, 2024
Merged

Add dof #17798

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading