Skip to content

Commit

Permalink
feat(globalFog): add feature of height fog (#250)
Browse files Browse the repository at this point in the history
Global fog effect added with high fog
Remove debug method for fog.
  • Loading branch information
hellmor committed Jul 15, 2023
1 parent acb1c7c commit e9e2f83
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 54 deletions.
12 changes: 2 additions & 10 deletions samples/post/Sample_Fog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,9 @@ class Sample_Fog {

{
let mat = new LitMaterial();
mat.baseMap = Engine3D.res.grayTexture;
mat.normalMap = Engine3D.res.normalTexture;
mat.aoMap = Engine3D.res.whiteTexture;
mat.maskMap = Engine3D.res.createTexture(32, 32, 255.0, 255.0, 0.0, 1);
mat.emissiveMap = Engine3D.res.blackTexture;
mat.roughness = 1.0;
mat.metallic = 0.0;
mat.roughness = 0.5;
mat.metallic = 0.5;

let floor = new Object3D();
let mr = floor.addComponent(MeshRenderer);
Expand All @@ -70,11 +66,7 @@ class Sample_Fog {

private createPlane(scene: Scene3D) {
let mat = new LitMaterial();
mat.baseMap = Engine3D.res.grayTexture;
mat.normalMap = Engine3D.res.normalTexture;
mat.aoMap = Engine3D.res.whiteTexture;
mat.maskMap = Engine3D.res.createTexture(32, 32, 255.0, 255.0, 0.0, 1);
mat.emissiveMap = Engine3D.res.blackTexture;
mat.roughness = 1.0;
mat.metallic = 0.0;

Expand Down
6 changes: 5 additions & 1 deletion samples/utils/GUIUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@ export class GUIUtil {
});
GUIHelp.add(fog, 'start', -0.0, 1000.0, 0.0001);
GUIHelp.add(fog, 'end', -0.0, 1000.0, 0.0001);
GUIHelp.add(fog, 'height', -1000.0, 1000.0, 0.0001);
GUIHelp.add(fog, 'fogHeightScale', 0.0001, 1.0, 0.0001);
GUIHelp.add(fog, 'density', 0.0, 1.0, 0.0001);
GUIHelp.add(fog, 'ins', 0.0, 5.0, 0.0001);
GUIHelp.add(fog, 'skyFactor', 0.0, 1.0, 0.0001);
GUIHelp.add(fog, 'skyRoughness', 0.0, 1.0, 0.0001);
GUIHelp.add(fog, 'overrideSkyFactor', 0.0, 1.0, 0.0001);
GUIHelp.add(fog, 'falloff', 0.0, 100.0, 0.01);
GUIHelp.add(fog, 'rayLength', 0.01, 2000.0, 0.01);
GUIHelp.add(fog, 'scatteringExponent', 1, 40.0, 0.001);
GUIHelp.add(fog, 'dirHeightLine', 0.0, 20.0, 0.01);
GUIHelp.addColor(fog, 'fogColor');
open && GUIHelp.open();
GUIHelp.endFolder();
Expand Down
12 changes: 8 additions & 4 deletions src/Engine3D.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,19 @@ export class Engine3D {
debug: false,
enable: false,
fogType: 0.0,
height: 100,
start: 800,
end: 200,
fogHeightScale: 0.1,
start: 400,
end: 10,
density: 0.02,
ins: 1,
ins: 0.5,
skyFactor: 0.5,
skyRoughness: 0.4,
overrideSkyFactor: 0.8,
fogColor: new Color(112 / 255, 61 / 255, 139 / 255, 1),
falloff: 0.7,
rayLength: 200.0,
scatteringExponent: 2.7,
dirHeightLine: 10.0,
},
ssao: {
enable: false,
Expand Down
95 changes: 75 additions & 20 deletions src/assets/shader/post/GlobalFog_shader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,43 @@ struct FragmentOutput {
${GlobalUniform}
#include "FastMathShader"
struct LightData {
index:f32,
lightType:i32,
radius:f32,
linear:f32,
position:vec3<f32>,
lightMatrixIndex:f32,
direction:vec3<f32>,
quadratic:f32,
lightColor:vec3<f32>,
intensity:f32,
innerCutOff :f32,
outerCutOff:f32,
range :f32,
castShadow:i32,
lightTangent:vec3<f32>,
ies:f32,
};
struct UniformData {
fogColor : vec4<f32>,
fogType : f32 ,
height : f32 ,
fogHeightScale : f32 ,
start: f32,
end: f32,
density : f32 ,
ins : f32 ,
falloff : f32 ,
rayLength : f32 ,
scatteringExponent : f32 ,
dirHeightLine : f32 ,
skyFactor: f32,
skyRoughness: f32,
overrideSkyFactor: f32,
Expand Down Expand Up @@ -51,13 +79,22 @@ var prefilterMap: texture_cube<f32>;
var<uniform> global : UniformData;
var<private> varying_uv: vec2<f32>;
fn LinearToGammaSpace(linRGB: vec3<f32>) -> vec3<f32> {
@group(2) @binding(1)
var<storage,read> lightBuffer: array<LightData>;
var<private> texPosition: vec4<f32>;
var<private> texNormal: vec4<f32>;
var<private> texColor: vec4<f32>;
fn LinearToGammaSpace(linRGB: vec3<f32>) -> vec3<f32>
{
var linRGB1 = max(linRGB, vec3<f32>(0.0));
linRGB1 = pow(linRGB1, vec3<f32>(0.4166666567325592));
return max(((1.0549999475479126 * linRGB1) - vec3<f32>(0.054999999701976776)), vec3<f32>(0.0));
}
fn getSkyColor(worldPosition:vec3<f32>, skyRoughness:f32, isHDRTexture:bool) -> vec3<f32>{
fn getSkyColor(worldPosition:vec3<f32>, skyRoughness:f32, isHDRTexture:bool) -> vec3<f32>
{
let cameraPosition = vec3<f32>(globalUniform.cameraWorldMatrix[3].xyz);
let rayDirection = normalize(vec3<f32>(worldPosition.xyz - cameraPosition));
let calcRoughness = clamp(skyRoughness, 0.0, 1.0);
Expand All @@ -66,16 +103,11 @@ fn getSkyColor(worldPosition:vec3<f32>, skyRoughness:f32, isHDRTexture:bool) ->
if(isHDRTexture){
prefilterColor = vec4<f32>(LinearToGammaSpace(vec3<f32>(prefilterColor.xyz)), prefilterColor.w);
}
return prefilterColor.xyz * globalUniform.skyExposure;
}
var<private> texPosition: vec4<f32>;
var<private> texNormal: vec4<f32>;
var<private> texColor: vec4<f32>;
return prefilterColor.xyz * globalUniform.skyExposure;
}
@fragment
fn main(@location(0) fragUV: vec2<f32>,
@builtin(position) coord: vec4<f32>) -> FragmentOutput {
fn main(@location(0) fragUV: vec2<f32>, @builtin(position) coord: vec4<f32>) -> FragmentOutput {
var texCoord = vec2<f32>(fragUV.x, 1.0 - fragUV.y);
texPosition = textureSample(positionMap, positionMapSampler, texCoord) ;
texNormal = textureSample(normalMap, normalMapSampler, texCoord) ;
Expand All @@ -97,16 +129,19 @@ fn main(@location(0) fragUV: vec2<f32>,
}else{
opColor = mix(texColor.rgb, global.fogColor.xyz, fogFactor);
}
let sunLight = lightBuffer[0] ;
var inScatteringValue = inScatterIng(sunLight.direction, texPosition.xyz, sunLight.lightColor);
opColor += inScatteringValue;
}
return FragmentOutput(vec4<f32>(opColor.xyz, texColor.a));
}
fn calcFogFactor() -> f32{
fn calcFogFactor() -> f32
{
var cameraPos = globalUniform.cameraWorldMatrix[3].xyz ;
let dis = texNormal.w * distance(cameraPos,texPosition.xyz);
let height = texPosition.y ;
//var heightFactor = computeFog((dis + height) / 2.0 );
var heightFactor = computeFog((dis));
let dis = distance(cameraPos, texPosition.xyz);
var heightFactor = computeFog(dis) + cFog(-texPosition.y);
return clamp(global.ins * heightFactor,0.0,1.0);
}
Expand All @@ -127,16 +162,36 @@ fn blendSkyColor() -> vec3<f32>
}
fn computeFog(z:f32) -> f32 {
fn computeFog(z:f32) -> f32
{
var fog = 0.0;
if( global.fogType == 0.0 ){
if( global.fogType < 0.5 ){
fog = (global.end - z) / (global.end - global.start);
}else if(global.fogType == 1.0 ){
}else if(global.fogType < 1.5 ){
fog = exp2(-global.density * z);
}else if(global.fogType == 2.0 ){
}else if(global.fogType == 2.5 ){
fog = global.density * z;
fog = exp2(-fog * fog);
}
return max(fog,0.0);
}
fn cFog(y:f32) -> f32
{
let fogDensity = global.density * exp(global.fogHeightScale * y);
let fogFactor = (1.0 - exp2(-global.falloff)) / global.falloff ;
let fog = fogDensity * fogFactor * max(global.rayLength - global.start, 0.0);
return max(fog,0.0);
}
fn inScatterIng(sunDir:vec3<f32>, worldPos:vec3<f32>, sunColor:vec3<f32>) -> vec3<f32>
{
let viewDir = normalize(globalUniform.CameraPos.xyz - worldPos.xyz) ;
let VoL = saturate(dot(viewDir,sunDir)) ;
var scatter = pow(VoL,global.scatteringExponent);
scatter *= (1.0-saturate(exp2(-global.dirHeightLine)));
return vec3<f32>(scatter*sunColor);
}
`;


0 comments on commit e9e2f83

Please sign in to comment.