Add parallel compiler
This commit is contained in:
parent
adbd933955
commit
36c64554f5
14 changed files with 260 additions and 181 deletions
|
|
@ -10,18 +10,18 @@ export class RenderingPass {
|
|||
|
||||
constructor(
|
||||
gl: WebGL2RenderingContext,
|
||||
shaderSources: [string, string],
|
||||
drawableDescriptors: Array<DrawableDescriptor>,
|
||||
private frame: FrameBuffer,
|
||||
substitutions: { [name: string]: any },
|
||||
private tileMultiplier: number
|
||||
) {
|
||||
this.program = new UniformArrayAutoScalingProgram(
|
||||
gl,
|
||||
shaderSources,
|
||||
drawableDescriptors,
|
||||
substitutions
|
||||
);
|
||||
this.program = new UniformArrayAutoScalingProgram(gl);
|
||||
}
|
||||
|
||||
public async initialize(
|
||||
shaderSources: [string, string],
|
||||
descriptors: Array<DrawableDescriptor>,
|
||||
substitutions: { [name: string]: any }
|
||||
): Promise<void> {
|
||||
await this.program.initialize(shaderSources, descriptors, substitutions);
|
||||
}
|
||||
|
||||
public addDrawable(drawable: Drawable) {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ float shadowTransparency(float startingDistance, float lightCenterDistance, vec2
|
|||
}
|
||||
|
||||
|
||||
#ifdef CIRCLE_LIGHT_COUNT
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
uniform struct CircleLight {
|
||||
vec2 center;
|
||||
|
|
@ -91,7 +92,9 @@ float shadowTransparency(float startingDistance, float lightCenterDistance, vec2
|
|||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FLASHLIGHT_COUNT
|
||||
#if FLASHLIGHT_COUNT > 0
|
||||
uniform struct Flashlight {
|
||||
vec2 center;
|
||||
|
|
@ -120,6 +123,7 @@ float shadowTransparency(float startingDistance, float lightCenterDistance, vec2
|
|||
);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
out vec4 fragmentColor;
|
||||
void main() {
|
||||
|
|
@ -129,20 +133,25 @@ void main() {
|
|||
float startingDistance = getDistance(uvCoordinates, colorAtPosition);
|
||||
|
||||
if (startingDistance < 0.0) {
|
||||
#ifdef CIRCLE_LIGHT_COUNT
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
for (int i = 0; i < CIRCLE_LIGHT_COUNT; i++) {
|
||||
lighting += colorInPositionInside(circleLights[i]);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FLASHLIGHT_COUNT
|
||||
#if FLASHLIGHT_COUNT > 0
|
||||
for (int i = 0; i < FLASHLIGHT_COUNT; i++) {
|
||||
lighting += colorInPositionInside(flashlights[i], normalize(flashlightDirections[i]));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
colorAtPosition = vec3(1.0);
|
||||
|
||||
#ifdef CIRCLE_LIGHT_COUNT
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
for (int i = 0; i < CIRCLE_LIGHT_COUNT; i++) {
|
||||
vec2 direction = normalize(circleLightDirections[i]) / squareToAspectRatioTimes2;
|
||||
|
|
@ -153,7 +162,9 @@ void main() {
|
|||
lighting += lightColorAtPosition * shadowTransparency(startingDistance, lightCenterDistance, direction);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FLASHLIGHT_COUNT
|
||||
#if FLASHLIGHT_COUNT > 0
|
||||
for (int i = 0; i < FLASHLIGHT_COUNT; i++) {
|
||||
vec2 originalDirection = normalize(flashlightDirections[i]);
|
||||
|
|
@ -169,6 +180,7 @@ void main() {
|
|||
lighting += lightColorAtPosition * shadowTransparency(startingDistance, lightCenterDistance, direction);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
fragmentColor = vec4(colorAtPosition * lighting, 1.0);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ out vec2 uvCoordinates;
|
|||
|
||||
uniform vec2 squareToAspectRatio;
|
||||
|
||||
#ifdef CIRCLE_LIGHT_COUNT
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
uniform struct CircleLight {
|
||||
vec2 center;
|
||||
|
|
@ -21,7 +22,9 @@ uniform vec2 squareToAspectRatio;
|
|||
|
||||
out vec2[CIRCLE_LIGHT_COUNT] circleLightDirections;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FLASHLIGHT_COUNT
|
||||
#if FLASHLIGHT_COUNT > 0
|
||||
uniform struct Flashlight {
|
||||
vec2 center;
|
||||
|
|
@ -32,6 +35,7 @@ uniform vec2 squareToAspectRatio;
|
|||
|
||||
out vec2[FLASHLIGHT_COUNT] flashlightDirections;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
vec3 vertexPosition2D = vec3(vertexPosition.xy, 1.0) * modelTransform;
|
||||
|
|
@ -44,15 +48,19 @@ void main() {
|
|||
0.0, 0.0, 1.0
|
||||
)).xy;
|
||||
|
||||
#ifdef CIRCLE_LIGHT_COUNT
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
for (int i = 0; i < CIRCLE_LIGHT_COUNT; i++) {
|
||||
circleLightDirections[i] = circleLights[i].center - position;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FLASHLIGHT_COUNT
|
||||
#if FLASHLIGHT_COUNT > 0
|
||||
for (int i = 0; i < FLASHLIGHT_COUNT; i++) {
|
||||
flashlightDirections[i] = flashlights[i].center - position;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { vec2, vec3 } from 'gl-matrix';
|
||||
import { Drawable } from '../../drawables/drawable';
|
||||
import { DrawableDescriptor } from '../../drawables/drawable-descriptor';
|
||||
import { CircleLight } from '../../drawables/lights/circle-light';
|
||||
import { Flashlight } from '../../drawables/lights/flashlight';
|
||||
import { DefaultFrameBuffer } from '../graphics-library/frame-buffer/default-frame-buffer';
|
||||
import { IntermediateFrameBuffer } from '../graphics-library/frame-buffer/intermediate-frame-buffer';
|
||||
import { getWebGl2Context } from '../graphics-library/helper/get-webgl2-context';
|
||||
import { WebGlStopwatch } from '../graphics-library/helper/stopwatch';
|
||||
import { ParallelCompiler } from '../graphics-library/parallel-compiler';
|
||||
import { FpsAutoscaler } from './fps-autoscaler';
|
||||
import { Insights } from './insights';
|
||||
import { Renderer } from './renderer';
|
||||
|
|
@ -29,6 +28,7 @@ export class WebGl2Renderer implements Renderer {
|
|||
private lightingFrameBuffer: DefaultFrameBuffer;
|
||||
private passes: Passes;
|
||||
private autoscaler: FpsAutoscaler;
|
||||
private settings: WebGl2RendererSettings;
|
||||
|
||||
private static defaultSettings: WebGl2RendererSettings = {
|
||||
enableHighDpiRendering: true,
|
||||
|
|
@ -42,24 +42,26 @@ export class WebGl2Renderer implements Renderer {
|
|||
|
||||
constructor(
|
||||
private canvas: HTMLCanvasElement,
|
||||
descriptors: Array<DrawableDescriptor>,
|
||||
palette: Array<vec3>,
|
||||
private descriptors: Array<DrawableDescriptor>,
|
||||
private palette: Array<vec3>,
|
||||
settingsOverrides: Partial<WebGl2RendererSettings>
|
||||
) {
|
||||
const settings = { ...WebGl2Renderer.defaultSettings, ...settingsOverrides };
|
||||
this.settings = { ...WebGl2Renderer.defaultSettings, ...settingsOverrides };
|
||||
|
||||
this.gl = getWebGl2Context(canvas);
|
||||
|
||||
ParallelCompiler.initialize(this.gl);
|
||||
|
||||
this.distanceFieldFrameBuffer = new IntermediateFrameBuffer(
|
||||
this.gl,
|
||||
settings.enableHighDpiRendering
|
||||
this.settings.enableHighDpiRendering
|
||||
);
|
||||
this.lightingFrameBuffer = new DefaultFrameBuffer(
|
||||
this.gl,
|
||||
settings.enableHighDpiRendering
|
||||
this.settings.enableHighDpiRendering
|
||||
);
|
||||
|
||||
this.passes = this.createPasses(descriptors, palette, settings);
|
||||
this.passes = this.createPasses();
|
||||
|
||||
this.uniformsProvider = new UniformsProvider(this.gl);
|
||||
|
||||
|
|
@ -71,7 +73,7 @@ export class WebGl2Renderer implements Renderer {
|
|||
(this.uniformsProvider.softShadowsEnabled = v as boolean),
|
||||
});
|
||||
|
||||
if (settings.enableStopwatch) {
|
||||
if (this.settings.enableStopwatch) {
|
||||
try {
|
||||
this.stopwatch = new WebGlStopwatch(this.gl);
|
||||
} catch {
|
||||
|
|
@ -81,40 +83,49 @@ export class WebGl2Renderer implements Renderer {
|
|||
}
|
||||
|
||||
@Insights.measure('create render passes')
|
||||
private createPasses(
|
||||
descriptors: Array<DrawableDescriptor>,
|
||||
palette: Array<vec3>,
|
||||
settings: WebGl2RendererSettings
|
||||
): Passes {
|
||||
const allDescriptors = [
|
||||
...descriptors,
|
||||
CircleLight.descriptor,
|
||||
Flashlight.descriptor,
|
||||
];
|
||||
|
||||
private createPasses(): Passes {
|
||||
return {
|
||||
[RenderingPassName.distance]: new RenderingPass(
|
||||
this.gl,
|
||||
[distanceVertexShader, distanceFragmentShader],
|
||||
allDescriptors.filter(WebGl2Renderer.hasSdf),
|
||||
this.distanceFieldFrameBuffer,
|
||||
settings.shaderMacros,
|
||||
settings.tileMultiplier
|
||||
this.settings.tileMultiplier
|
||||
),
|
||||
[RenderingPassName.pixel]: new RenderingPass(
|
||||
this.gl,
|
||||
[lightsVertexShader, lightsFragmentShader],
|
||||
allDescriptors.filter((d) => !WebGl2Renderer.hasSdf(d)),
|
||||
this.lightingFrameBuffer,
|
||||
{
|
||||
palette: this.generatePaletteCode(palette),
|
||||
...settings.shaderMacros,
|
||||
},
|
||||
settings.tileMultiplier
|
||||
this.settings.tileMultiplier
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@Insights.measure('initialize render passes')
|
||||
public async initialize(): Promise<void> {
|
||||
const promises: Array<Promise<void>> = [];
|
||||
|
||||
promises.push(
|
||||
this.passes[RenderingPassName.distance].initialize(
|
||||
[distanceVertexShader, distanceFragmentShader],
|
||||
this.descriptors.filter(WebGl2Renderer.hasSdf),
|
||||
this.settings.shaderMacros
|
||||
)
|
||||
);
|
||||
|
||||
promises.push(
|
||||
this.passes[RenderingPassName.pixel].initialize(
|
||||
[lightsVertexShader, lightsFragmentShader],
|
||||
this.descriptors.filter((d) => !WebGl2Renderer.hasSdf(d)),
|
||||
{
|
||||
palette: this.generatePaletteCode(this.palette),
|
||||
...this.settings.shaderMacros,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ParallelCompiler.compilePrograms();
|
||||
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
public get insights(): any {
|
||||
return Insights.values;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue