Skip to content

Commit c665243

Browse files
committed
cp
1 parent 0c87ce4 commit c665243

13 files changed

+440
-119
lines changed

graphics/index.ts

-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
export * from './camera';
22
export * from './transform';
3-
export * from './plate-ocean-renderer';
4-
export * from './tile-ocean-renderer';
5-
export * from './projected-grid-renderer';
63
export * from './mesh';
74
export * from './gpu';
85
export * from './texture-renderer';

graphics/mesh.ts

+18-11
Original file line numberDiff line numberDiff line change
@@ -147,26 +147,33 @@ export const createPlane = (resolution: number): Mesh => {
147147
};
148148
};
149149

150-
export const createNDCGrid = (resolution: number): Mesh => {
150+
export const createNDCGrid = (
151+
resolutionX: number,
152+
resolutionY: number,
153+
marginX = 1.0,
154+
marginY = 1.0
155+
): Mesh => {
151156
const vertices: vec3[] = [];
152157
const indices: number[] = [];
153-
const N = resolution;
154-
const L = 1.0;
155-
const delta = (2.0 * L) / (N - 1);
156-
const offset = vec3.fromValues(-L, -L, -1.0);
157158

158-
for (let i = 0; i < N - 1; i++) {
159-
for (let j = 0; j < N - 1; j++) {
160-
let v0 = vec3.fromValues(j * delta, i * delta, 0.0);
159+
const Lx = 1.0 + marginX;
160+
const Ly = 1.0 + marginY;
161+
const deltaX = (2.0 * Lx) / (resolutionX - 1);
162+
const deltaY = (2.0 * Ly) / (resolutionY - 1);
163+
const offset = vec3.fromValues(-Lx, -Ly, -1.0);
164+
165+
for (let i = 0; i < resolutionY - 1; i++) {
166+
for (let j = 0; j < resolutionX - 1; j++) {
167+
let v0 = vec3.fromValues(j * deltaX, i * deltaY, 0.0);
161168
vec3.add(v0, v0, offset);
162169

163-
let v1 = vec3.fromValues((j + 1) * delta, i * delta, 0.0);
170+
let v1 = vec3.fromValues((j + 1) * deltaX, i * deltaY, 0.0);
164171
vec3.add(v1, v1, offset);
165172

166-
let v2 = vec3.fromValues((j + 1) * delta, (i + 1) * delta, 0.0);
173+
let v2 = vec3.fromValues((j + 1) * deltaX, (i + 1) * deltaY, 0.0);
167174
vec3.add(v2, v2, offset);
168175

169-
let v3 = vec3.fromValues(j * delta, (i + 1) * delta, 0.0);
176+
let v3 = vec3.fromValues(j * deltaX, (i + 1) * deltaY, 0.0);
170177
vec3.add(v3, v3, offset);
171178

172179
// indices.push(vertices.length + 1, vertices.length, vertices.length + 2);

graphics/programs/projected-grid.ts

+31-10
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,46 @@ export const vs = `#version 300 es
22
33
layout(location = 0) in vec3 position;
44
5-
uniform mat4 invViewProjMat;
5+
uniform mat4 invProjView;
66
uniform mat4 viewMat;
77
uniform mat4 projMat;
88
uniform vec3 pos;
9-
10-
out highp vec2 _xz;
11-
9+
uniform float sizes[3];
10+
uniform float croppinesses[3];
11+
uniform float scale;
12+
13+
uniform sampler2D dx_hy_dz_dxdz0;
14+
uniform sampler2D sx_sz_dxdx_dzdz0;
15+
uniform sampler2D dx_hy_dz_dxdz1;
16+
uniform sampler2D sx_sz_dxdx_dzdz1;
17+
uniform sampler2D dx_hy_dz_dxdz2;
18+
uniform sampler2D sx_sz_dxdx_dzdz2;
19+
20+
out vec3 _position;
21+
out vec2 _xz;
22+
23+
vec3 getDisplacement(in vec2 xz) {
24+
vec2 uv0 = xz / sizes[0];
25+
vec2 uv1 = xz / sizes[1];
26+
vec2 uv2 = xz / sizes[2];
27+
28+
return
29+
texture(dx_hy_dz_dxdz0, uv0).xyz * vec3(croppinesses[0], 1.0f, croppinesses[0]) +
30+
texture(dx_hy_dz_dxdz1, uv1).xyz * vec3(croppinesses[1], 1.0f, croppinesses[1]) +
31+
texture(dx_hy_dz_dxdz2, uv2).xyz * vec3(croppinesses[2], 1.0f, croppinesses[2]);
32+
}
1233
void main()
1334
{
14-
vec4 homogeneous = invViewProjMat * vec4(position, 1.0f);
15-
vec3 world = homogeneous.xyz / homogeneous.w;
16-
vec3 ray = world - pos;
35+
vec4 homogeneous = invProjView * vec4(position, 1.0f);
36+
vec3 ray = normalize(homogeneous.xyz / homogeneous.w);
1737
1838
if(ray.y >= 0.0f) { // beyond horizon
1939
gl_Position = vec4(position.x, position.y, 2.0f, 1.0f);
2040
} else {
21-
world = ray * -pos.y / ray.y + pos;
22-
_xz = world.xz;
23-
gl_Position = projMat * viewMat * vec4(world, 1.0f);
41+
_position = ray * -pos.y / ray.y + pos;
42+
_xz = _position.xz;
43+
_position = _position + getDisplacement(_xz);
44+
gl_Position = projMat * viewMat * vec4(_position, 1.0f);
2445
}
2546
}
2647
`;

graphics/projected-grid-renderer.ts

-81
This file was deleted.

renderer/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './plate-ocean-renderer';
2+
export * from './tile-ocean-renderer';
3+
export * from './projected-grid-renderer';
4+

renderer/ocean-renderer-interface.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Camera } from '../graphics';
2+
import { OceanField } from '../ocean';
3+
4+
export interface OceanRendererInterface<S> {
5+
render(camera: Camera, oceanField: OceanField): void;
6+
getSettings(): Readonly<S>;
7+
setSettings(settings: Partial<S>): void;
8+
}

graphics/plate-ocean-renderer.ts renamed to renderer/plate-ocean-renderer.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { BehaviorSubject } from 'rxjs';
33
import { distinctUntilChanged, switchMap, debounceTime } from 'rxjs/operators';
44
import { isEqual } from 'lodash-es';
55

6-
import { Geometry, Gpu, Mesh, ShaderProgram } from './gpu';
7-
import { Camera } from './camera';
6+
import { Geometry, Gpu, Mesh, ShaderProgram, Camera } from '../graphics';
7+
import { OceanRendererInterface } from './ocean-renderer-interface';
88
import { vs as oceanvs, fs as oceanfs } from './programs/ocean';
99
import { OceanField } from '../ocean';
1010
import { ThreadWorker } from '../thread';
11+
1112
// @ts-ignore:
1213
import { createDisc } from './mesh';
1314

@@ -21,7 +22,7 @@ export interface PlateOceanRendererSettings {
2122
offset: number;
2223
}
2324

24-
export const plateDefaultSettings: Readonly<PlateOceanRendererSettings> = {
25+
const defaultSettings: Readonly<PlateOceanRendererSettings> = {
2526
rings: 512,
2627
segments: 512,
2728
delta: 0.1,
@@ -31,11 +32,13 @@ export const plateDefaultSettings: Readonly<PlateOceanRendererSettings> = {
3132

3233
type ThreadWorkerInput = PlateOceanRendererSettings;
3334

34-
export class PlateOceanRenderer {
35+
export class PlateOceanRenderer
36+
implements OceanRendererInterface<PlateOceanRendererSettings>
37+
{
3538
private readonly shader: ShaderProgram;
3639
private readonly worker: ThreadWorker<ThreadWorkerInput, Mesh>;
3740
private readonly settings$ = new BehaviorSubject<PlateOceanRendererSettings>({
38-
...plateDefaultSettings,
41+
...defaultSettings,
3942
});
4043
private geometry: Geometry;
4144

renderer/programs/ocean.ts

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
export const vs = `#version 300 es
2+
3+
layout(location = 0) in vec3 position;
4+
5+
uniform mat4 viewMat;
6+
uniform mat4 worldMat;
7+
uniform mat4 projMat;
8+
uniform float sizes[3];
9+
uniform float croppinesses[3];
10+
uniform float scale;
11+
12+
uniform sampler2D dx_hy_dz_dxdz0;
13+
uniform sampler2D sx_sz_dxdx_dzdz0;
14+
uniform sampler2D dx_hy_dz_dxdz1;
15+
uniform sampler2D sx_sz_dxdx_dzdz1;
16+
uniform sampler2D dx_hy_dz_dxdz2;
17+
uniform sampler2D sx_sz_dxdx_dzdz2;
18+
19+
out vec3 _position;
20+
out vec2 _xz;
21+
22+
vec3 getDisplacement(in vec2 xz) {
23+
vec2 uv0 = xz / sizes[0];
24+
vec2 uv1 = xz / sizes[1];
25+
vec2 uv2 = xz / sizes[2];
26+
27+
return
28+
texture(dx_hy_dz_dxdz0, uv0).xyz * vec3(croppinesses[0], 1.0f, croppinesses[0]) +
29+
texture(dx_hy_dz_dxdz1, uv1).xyz * vec3(croppinesses[1], 1.0f, croppinesses[1]) +
30+
texture(dx_hy_dz_dxdz2, uv2).xyz * vec3(croppinesses[2], 1.0f, croppinesses[2]);
31+
}
32+
33+
void main()
34+
{
35+
vec2 xz = vec3(worldMat * vec4(position * scale, 1.0f)).xz;
36+
_position = position * scale + getDisplacement(xz);
37+
_position = vec3(worldMat * vec4(_position, 1.0f));
38+
_xz = xz;
39+
gl_Position = projMat * viewMat * vec4(_position, 1.0f);
40+
}
41+
`;
42+
43+
export const fs = `#version 300 es
44+
precision highp float;
45+
46+
layout(location = 0) out vec4 color;
47+
48+
in vec3 _position;
49+
in vec2 _xz;
50+
51+
uniform vec3 pos;
52+
uniform float foamSpreading;
53+
uniform float foamContrast;
54+
uniform float sizes[3];
55+
uniform float croppinesses[3];
56+
57+
uniform sampler2D dx_hy_dz_dxdz0;
58+
uniform sampler2D sx_sz_dxdx_dzdz0;
59+
uniform sampler2D dx_hy_dz_dxdz1;
60+
uniform sampler2D sx_sz_dxdx_dzdz1;
61+
uniform sampler2D dx_hy_dz_dxdz2;
62+
uniform sampler2D sx_sz_dxdx_dzdz2;
63+
64+
vec4 jacobian(float dxdx, float dxdz, float dzdz) {
65+
float Jxx = 1.0f + dxdx;
66+
float Jxz = dxdz;
67+
float Jzz = 1.0f + dzdz;
68+
return vec4(Jxx, Jxz, Jxz, Jzz);
69+
}
70+
71+
float det(vec4 jacobian) {
72+
return jacobian.x * jacobian.w - jacobian.y * jacobian.z;
73+
}
74+
75+
vec3 getNormal(in vec2 xz) {
76+
vec2 uv0 = xz / sizes[0];
77+
vec2 uv1 = xz / sizes[1];
78+
vec2 uv2 = xz / sizes[2];
79+
80+
vec4 _sx_sz_dxdx_dzdz0 = texture(sx_sz_dxdx_dzdz0, uv0).xyzw;
81+
vec4 _sx_sz_dxdx_dzdz1 = texture(sx_sz_dxdx_dzdz1, uv1).xyzw;
82+
vec4 _sx_sz_dxdx_dzdz2 = texture(sx_sz_dxdx_dzdz2, uv2).xyzw;
83+
84+
float sx = _sx_sz_dxdx_dzdz0.x + _sx_sz_dxdx_dzdz1.x +_sx_sz_dxdx_dzdz2.x;
85+
float sz = _sx_sz_dxdx_dzdz0.y + _sx_sz_dxdx_dzdz1.y +_sx_sz_dxdx_dzdz2.y;
86+
float dxdx = _sx_sz_dxdx_dzdz0.z * croppinesses[0] + _sx_sz_dxdx_dzdz1.z * croppinesses[1] + _sx_sz_dxdx_dzdz2.z * croppinesses[2];
87+
float dzdz = _sx_sz_dxdx_dzdz0.w * croppinesses[0] + _sx_sz_dxdx_dzdz1.w * croppinesses[1] + _sx_sz_dxdx_dzdz2.w * croppinesses[2];
88+
89+
vec2 slope = vec2(sx / (1.0f + dxdx), sz / (1.0f + dzdz));
90+
91+
return normalize(vec3(-slope.x, 1.0f, -slope.y));
92+
}
93+
94+
float getFoam(in vec2 xz) {
95+
vec2 uv0 = xz / sizes[0];
96+
vec2 uv1 = xz / sizes[1];
97+
vec2 uv2 = xz / sizes[2];
98+
99+
vec2 dxdx_dzdz0 = texture(sx_sz_dxdx_dzdz0, uv0).zw;
100+
vec2 dxdx_dzdz1 = texture(sx_sz_dxdx_dzdz1, uv1).zw;
101+
vec2 dxdx_dzdz2 = texture(sx_sz_dxdx_dzdz2, uv2).zw;
102+
103+
float dxdz0 = texture(dx_hy_dz_dxdz0, uv0).w;
104+
float dxdz1 = texture(dx_hy_dz_dxdz1, uv1).w;
105+
float dxdz2 = texture(dx_hy_dz_dxdz2, uv2).w;
106+
107+
vec2 dxdx_dzdz = dxdx_dzdz0 * croppinesses[0] + dxdx_dzdz1 * croppinesses[1] + dxdx_dzdz2 * croppinesses[2];
108+
float dxdz = dxdz0 * croppinesses[0] + dxdz1 * croppinesses[1] + dxdz2 * croppinesses[2];
109+
110+
float val = det(jacobian(dxdx_dzdz.x, dxdz, dxdx_dzdz.y));
111+
return pow(-min(0.0f, val - foamSpreading), foamContrast);
112+
}
113+
114+
vec3 surface(in vec3 normal, in vec3 view) {
115+
const vec3 upwelling = vec3(0.0, 0.2, 0.3);
116+
const vec3 sky = vec3(0.69, 0.84, 1.0);
117+
const vec3 mist = vec3(0.34, 0.42, 0.5);
118+
const float nShell = 1.34f;
119+
const float kDiffuse = 0.91f;
120+
121+
float reflectivity;
122+
float costhetai = abs(dot(normal, normalize(view)));
123+
float thetai = acos(costhetai);
124+
float sinthetat = sin(thetai) / nShell;
125+
float thetat = asin(sinthetat);
126+
127+
if(thetai == 0.0)
128+
{
129+
reflectivity = (nShell - 1.0f) / (nShell + 1.0f);
130+
reflectivity = reflectivity * reflectivity;
131+
}
132+
else
133+
{
134+
float fs = sin(thetat - thetai) / sin(thetat + thetai);
135+
float ts = tan(thetat - thetai) / tan(thetat + thetai);
136+
reflectivity = 0.5 * (fs * fs + ts * ts );
137+
}
138+
139+
float falloff = exp(-length(view) * 1.0e-3) * kDiffuse;
140+
vec3 surf = reflectivity * sky + (1.0f - reflectivity) * upwelling;
141+
return falloff * surf + (1.0f - falloff) * mist;
142+
}
143+
144+
void main()
145+
{
146+
float f = getFoam(_xz);
147+
vec3 n = getNormal(_xz);
148+
const vec3 foam = vec3(1.0f);
149+
vec3 water = surface(n, pos - _position);
150+
color = vec4(mix(water, foam, f), 1.0f);
151+
}
152+
`;

0 commit comments

Comments
 (0)