/
FogShader.ts
121 lines (95 loc) · 4.03 KB
/
FogShader.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { InstancedTexturePositionsColoredShader } from "./InstancedTexturePositionsColoredShader";
import { InstancedTexturePositionsShader } from "./InstancedTexturePositionsShader";
import { ShaderCommonFunctions } from "./ShaderCommonFunctions";
export class FogShader extends InstancedTexturePositionsColoredShader {
fogStartDistance: WebGLUniformLocation | undefined;
fogDistance: WebGLUniformLocation | undefined;
heightFogParams: WebGLUniformLocation | undefined;
heightOffset: WebGLUniformLocation | undefined;
view_matrix: WebGLUniformLocation | undefined;
model_matrix: WebGLUniformLocation | undefined;
texCubemap: WebGLUniformLocation | undefined;
static readonly FOG_VERTEX_UNIFORMS_VARYINGS = `
uniform vec2 heightOffset; // x: random positive/negative offset; y: fixed offset
uniform float fogDistance;
uniform float fogStartDistance;
out float vFogAmount;
out float vFogZ;
out mediump vec2 vTexCoord;
const float ZERO = 0.0;
const float ONE = 1.0;
`;
static readonly FOG_FRAGMENT_UNIFORMS_VARYINGS = `
in float vFogAmount;
in float vFogZ;
uniform vec2 heightFogParams;
in vec3 texCoord;
uniform samplerCube texCubemap;
const float ZERO = 0.0;
const float ONE = 1.0;
`;
static readonly FOG_AMOUNT_VERTEX = `
float distanceFog = clamp((length(gl_Position) - fogStartDistance) / fogDistance, ZERO, ONE);
vFogAmount = clamp(distanceFog, ZERO, ONE);
`;
static readonly FOG_VERTEX_MAIN = `
${this.FOG_AMOUNT_VERTEX}
vFogZ = vertex.z;
texCoord = inverse(mat3(view_matrix)) * (view_matrix * vertex).xyz;
`;
static readonly FOG_AMOUNT_FRAGMENT = `
float heightFog = clamp(1.0 - ((vFogZ + heightFogParams.x) * heightFogParams.y), ZERO, ONE);
float fogAmount = clamp(vFogAmount + heightFog, ZERO, ONE);
`;
static readonly FOG_FRAGMENT_MAIN = `
${this.FOG_AMOUNT_FRAGMENT}
vec4 fogColor = texture(texCubemap, texCoord);
`;
fillCode() {
this.vertexShaderCode = `#version 300 es
precision highp float;
uniform mat4 view_proj_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
out vec3 texCoord;
uniform vec2 uScale; // x: base scale for models; y: max random additional scale
uniform sampler2D sPositions;
uniform int uPositionOffset;
in vec2 rm_TexCoord0;
in vec4 rm_Vertex;
${ShaderCommonFunctions.RANDOM}
${ShaderCommonFunctions.ROTATION}
const float PI2 = 6.28318530718;
${FogShader.FOG_VERTEX_UNIFORMS_VARYINGS}
void main(void)
{
${InstancedTexturePositionsShader.COMMON_TRANSFORMS}
vertex.z += rotations.x * heightOffset.x + heightOffset.y;
gl_Position = view_proj_matrix * vertex;
vTexCoord = rm_TexCoord0;
${FogShader.FOG_VERTEX_MAIN}
}`;
this.fragmentShaderCode = `#version 300 es
precision mediump float;
uniform sampler2D sTexture;
uniform vec4 color;
in mediump vec2 vTexCoord;
out vec4 fragColor;
${FogShader.FOG_FRAGMENT_UNIFORMS_VARYINGS}
void main(void)
{
${FogShader.FOG_FRAGMENT_MAIN}
vec4 diffuse = texture(sTexture, vTexCoord) * color;
fragColor = mix(diffuse, fogColor, fogAmount);
}`;
}
fillUniformsAttributes() {
super.fillUniformsAttributes();
this.fogStartDistance = this.getUniform("fogStartDistance");
this.fogDistance = this.getUniform("fogDistance");
this.heightFogParams = this.getUniform("heightFogParams");
this.heightOffset = this.getUniform("heightOffset");
this.view_matrix = this.getUniform("view_matrix");
this.texCubemap = this.getUniform("texCubemap");
}
}