Feature: Add dedicated sky color support to distance fog pass
This commit is contained in:
@@ -38,6 +38,11 @@ export interface ResolvedDistanceFogParameters {
|
|||||||
fadeMargin: number;
|
fadeMargin: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DistanceFogSkyColorSource {
|
||||||
|
topColorHex: string;
|
||||||
|
horizonColorHex: string;
|
||||||
|
}
|
||||||
|
|
||||||
function clampNumber(value: number, min: number, max: number) {
|
function clampNumber(value: number, min: number, max: number) {
|
||||||
return Math.min(Math.max(value, min), max);
|
return Math.min(Math.max(value, min), max);
|
||||||
}
|
}
|
||||||
@@ -120,6 +125,21 @@ export function shouldApplyDistanceFog(settings: AdvancedRenderingSettings) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createDistanceFogSkyColorSource(): DistanceFogSkyColorSource {
|
||||||
|
return {
|
||||||
|
topColorHex: "#ffffff",
|
||||||
|
horizonColorHex: "#ffffff"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function syncDistanceFogSkyColorSource(
|
||||||
|
target: DistanceFogSkyColorSource,
|
||||||
|
source: DistanceFogSkyColorSource
|
||||||
|
) {
|
||||||
|
target.topColorHex = source.topColorHex;
|
||||||
|
target.horizonColorHex = source.horizonColorHex;
|
||||||
|
}
|
||||||
|
|
||||||
export function resolveAdvancedRenderingPerspectiveCameraFar(
|
export function resolveAdvancedRenderingPerspectiveCameraFar(
|
||||||
settings: AdvancedRenderingSettings | null,
|
settings: AdvancedRenderingSettings | null,
|
||||||
defaultFar: number,
|
defaultFar: number,
|
||||||
@@ -189,6 +209,8 @@ uniform mat4 cameraProjectionMatrixInverse;
|
|||||||
uniform mat4 cameraWorldMatrix;
|
uniform mat4 cameraWorldMatrix;
|
||||||
uniform vec3 cameraWorldPosition;
|
uniform vec3 cameraWorldPosition;
|
||||||
uniform vec3 fogColor;
|
uniform vec3 fogColor;
|
||||||
|
uniform vec3 skyTopColor;
|
||||||
|
uniform vec3 skyHorizonColor;
|
||||||
uniform float nearDistance;
|
uniform float nearDistance;
|
||||||
uniform float farDistance;
|
uniform float farDistance;
|
||||||
uniform float renderDistance;
|
uniform float renderDistance;
|
||||||
@@ -249,23 +271,10 @@ float getDepthEdgeMask(float centerDistance) {
|
|||||||
return smoothstep(0.08, 0.5, normalizedDelta);
|
return smoothstep(0.08, 0.5, normalizedDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 sampleSkyAt(vec2 uv) {
|
vec3 sampleSkyColor(float horizon) {
|
||||||
float skyMask = smoothstep(BACKGROUND_DEPTH_THRESHOLD, 1.0, readDepth(uv));
|
vec3 generalSkyColor = mix(skyTopColor, skyHorizonColor, 0.72);
|
||||||
return mix(fogColor, texture2D(inputBuffer, uv).rgb, skyMask);
|
vec3 hazeSkyColor = mix(generalSkyColor, skyHorizonColor, horizon * 0.35);
|
||||||
}
|
return mix(fogColor, hazeSkyColor, skyBlend);
|
||||||
|
|
||||||
vec3 sampleSkyRow(float y) {
|
|
||||||
vec3 leftSky = sampleSkyAt(vec2(0.18, y));
|
|
||||||
vec3 centerSky = sampleSkyAt(vec2(0.5, y));
|
|
||||||
vec3 rightSky = sampleSkyAt(vec2(0.82, y));
|
|
||||||
return (leftSky + centerSky + rightSky) / 3.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 sampleSkyColor() {
|
|
||||||
vec3 upperSky = sampleSkyRow(0.96);
|
|
||||||
vec3 horizonSky = sampleSkyRow(0.58);
|
|
||||||
vec3 sampledSky = mix(upperSky, horizonSky, 0.58);
|
|
||||||
return mix(fogColor, sampledSky, skyBlend);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@@ -295,7 +304,7 @@ void main() {
|
|||||||
float heightTerm = mix(1.0, 0.66 + lowAltitude * 0.34, clamp(heightFalloff * 32.0, 0.0, 1.0));
|
float heightTerm = mix(1.0, 0.66 + lowAltitude * 0.34, clamp(heightFalloff * 32.0, 0.0, 1.0));
|
||||||
float haze = max(exponentialFog * (1.0 + horizon * horizonStrength * 0.72) * heightTerm, cutoffFog * (0.78 + horizon * 0.16));
|
float haze = max(exponentialFog * (1.0 + horizon * horizonStrength * 0.72) * heightTerm, cutoffFog * (0.78 + horizon * 0.16));
|
||||||
float fogAmount = clamp(haze * strength, 0.0, 0.96);
|
float fogAmount = clamp(haze * strength, 0.0, 0.96);
|
||||||
vec3 atmosphereColor = sampleSkyColor();
|
vec3 atmosphereColor = sampleSkyColor(horizon);
|
||||||
|
|
||||||
if (isBackground) {
|
if (isBackground) {
|
||||||
float skyHaze = clamp(horizon * horizonStrength * strength * skyBlend * 0.22, 0.0, 0.32);
|
float skyHaze = clamp(horizon * horizonStrength * strength * skyBlend * 0.22, 0.0, 0.32);
|
||||||
@@ -314,6 +323,7 @@ export class DistanceFogPass extends Pass {
|
|||||||
private readonly sourceCamera: PerspectiveCamera;
|
private readonly sourceCamera: PerspectiveCamera;
|
||||||
private readonly material: ShaderMaterial;
|
private readonly material: ShaderMaterial;
|
||||||
private readonly parameters: ResolvedDistanceFogParameters;
|
private readonly parameters: ResolvedDistanceFogParameters;
|
||||||
|
private readonly skyColorSource: DistanceFogSkyColorSource | null;
|
||||||
private readonly cameraNearFar = new Vector2();
|
private readonly cameraNearFar = new Vector2();
|
||||||
private readonly texelSize = new Vector2(1, 1);
|
private readonly texelSize = new Vector2(1, 1);
|
||||||
private readonly cameraProjectionMatrix = new Matrix4();
|
private readonly cameraProjectionMatrix = new Matrix4();
|
||||||
@@ -321,17 +331,25 @@ export class DistanceFogPass extends Pass {
|
|||||||
private readonly cameraWorldMatrix = new Matrix4();
|
private readonly cameraWorldMatrix = new Matrix4();
|
||||||
private readonly cameraWorldPosition = new Vector3();
|
private readonly cameraWorldPosition = new Vector3();
|
||||||
private readonly fogColor = new Color();
|
private readonly fogColor = new Color();
|
||||||
|
private readonly skyTopColor = new Color();
|
||||||
|
private readonly skyHorizonColor = new Color();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
camera: PerspectiveCamera,
|
camera: PerspectiveCamera,
|
||||||
parameters: ResolvedDistanceFogParameters
|
parameters: ResolvedDistanceFogParameters,
|
||||||
|
skyColorSource: DistanceFogSkyColorSource | null = null
|
||||||
) {
|
) {
|
||||||
super("DistanceFogPass");
|
super("DistanceFogPass");
|
||||||
|
|
||||||
this.sourceCamera = camera;
|
this.sourceCamera = camera;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
|
this.skyColorSource = skyColorSource;
|
||||||
this.needsDepthTexture = true;
|
this.needsDepthTexture = true;
|
||||||
this.fogColor.set(parameters.colorHex);
|
this.fogColor.set(parameters.colorHex);
|
||||||
|
this.skyTopColor.set(skyColorSource?.topColorHex ?? parameters.colorHex);
|
||||||
|
this.skyHorizonColor.set(
|
||||||
|
skyColorSource?.horizonColorHex ?? parameters.colorHex
|
||||||
|
);
|
||||||
|
|
||||||
this.material = new ShaderMaterial({
|
this.material = new ShaderMaterial({
|
||||||
name: "DistanceFogMaterial",
|
name: "DistanceFogMaterial",
|
||||||
@@ -350,6 +368,8 @@ export class DistanceFogPass extends Pass {
|
|||||||
cameraWorldMatrix: new Uniform(this.cameraWorldMatrix),
|
cameraWorldMatrix: new Uniform(this.cameraWorldMatrix),
|
||||||
cameraWorldPosition: new Uniform(this.cameraWorldPosition),
|
cameraWorldPosition: new Uniform(this.cameraWorldPosition),
|
||||||
fogColor: new Uniform(this.fogColor),
|
fogColor: new Uniform(this.fogColor),
|
||||||
|
skyTopColor: new Uniform(this.skyTopColor),
|
||||||
|
skyHorizonColor: new Uniform(this.skyHorizonColor),
|
||||||
nearDistance: new Uniform(parameters.nearDistance),
|
nearDistance: new Uniform(parameters.nearDistance),
|
||||||
farDistance: new Uniform(parameters.farDistance),
|
farDistance: new Uniform(parameters.farDistance),
|
||||||
renderDistance: new Uniform(parameters.renderDistance),
|
renderDistance: new Uniform(parameters.renderDistance),
|
||||||
@@ -399,6 +419,12 @@ export class DistanceFogPass extends Pass {
|
|||||||
this.cameraWorldPosition.setFromMatrixPosition(
|
this.cameraWorldPosition.setFromMatrixPosition(
|
||||||
this.sourceCamera.matrixWorld
|
this.sourceCamera.matrixWorld
|
||||||
);
|
);
|
||||||
|
this.skyTopColor.set(
|
||||||
|
this.skyColorSource?.topColorHex ?? this.parameters.colorHex
|
||||||
|
);
|
||||||
|
this.skyHorizonColor.set(
|
||||||
|
this.skyColorSource?.horizonColorHex ?? this.parameters.colorHex
|
||||||
|
);
|
||||||
this.material.uniforms.inputBuffer.value = inputBuffer.texture;
|
this.material.uniforms.inputBuffer.value = inputBuffer.texture;
|
||||||
this.material.uniforms.nearDistance.value = this.parameters.nearDistance;
|
this.material.uniforms.nearDistance.value = this.parameters.nearDistance;
|
||||||
this.material.uniforms.farDistance.value = this.parameters.farDistance;
|
this.material.uniforms.farDistance.value = this.parameters.farDistance;
|
||||||
|
|||||||
Reference in New Issue
Block a user