diff --git a/src/drawables/shapes/circle-factory.ts b/src/drawables/shapes/circle-factory.ts index b88b5cd..ad6c8b1 100644 --- a/src/drawables/shapes/circle-factory.ts +++ b/src/drawables/shapes/circle-factory.ts @@ -15,6 +15,10 @@ class CircleBase extends EmptyDrawable { } } +// Suffixing the GLSL names with a per-factory-invocation id lets multiple +// circle types (e.g. different colors) coexist in one compiled shader. +let _id = 0; + /** * @category Drawable */ @@ -23,27 +27,27 @@ export const CircleFactory = (color: vec3 | vec4 | number): typeof CircleBase => public static descriptor: DrawableDescriptor = { sdf: { shader: ` - uniform vec2 circleCenters[CIRCLE_COUNT]; - uniform float circleRadii[CIRCLE_COUNT]; - - float circleMinDistance(vec2 target, out vec4 color) { + uniform vec2 circleCenters${_id}[CIRCLE_COUNT${_id}]; + uniform float circleRadii${_id}[CIRCLE_COUNT${_id}]; + + float circleMinDistance${_id}(vec2 target, out vec4 color) { color = ${codeForColorAccess(color)}; float minDistance = 1000.0; - for (int i = 0; i < CIRCLE_COUNT; i++) { - float dist = distance(circleCenters[i], target) - circleRadii[i]; + for (int i = 0; i < CIRCLE_COUNT${_id}; i++) { + float dist = distance(circleCenters${_id}[i], target) - circleRadii${_id}[i]; minDistance = min(minDistance, dist); } - + return minDistance; } `, - distanceFunctionName: 'circleMinDistance', + distanceFunctionName: `circleMinDistance${_id}`, }, propertyUniformMapping: { - center: 'circleCenters', - radius: 'circleRadii', + center: `circleCenters${_id}`, + radius: `circleRadii${_id}`, }, - uniformCountMacroName: 'CIRCLE_COUNT', + uniformCountMacroName: `CIRCLE_COUNT${_id}`, shaderCombinationSteps: [0, 1, 2, 3, 8, 16], empty: new Circle(vec2.create(), 0), }; @@ -60,5 +64,7 @@ export const CircleFactory = (color: vec3 | vec4 | number): typeof CircleBase => } } + _id++; + return Circle; }; diff --git a/src/drawables/shapes/colorful-circle.ts b/src/drawables/shapes/colorful-circle.ts index 981db95..dbcf125 100644 --- a/src/drawables/shapes/colorful-circle.ts +++ b/src/drawables/shapes/colorful-circle.ts @@ -10,7 +10,7 @@ export class ColorfulCircle extends Drawable { uniform float colorfulCircleRadii[COLORFUL_CIRCLE_COUNT]; uniform int colorfulCircleColorIndex[COLORFUL_CIRCLE_COUNT]; - float circleMinDistance(vec2 target, out vec4 color) { + float colorfulCircleMinDistance(vec2 target, out vec4 color) { float minDistance = 1000.0; for (int i = 0; i < COLORFUL_CIRCLE_COUNT; i++) { float dist = distance(colorfulCircleCenters[i], target) - colorfulCircleRadii[i]; @@ -23,7 +23,7 @@ export class ColorfulCircle extends Drawable { return minDistance; } `, - distanceFunctionName: 'circleMinDistance', + distanceFunctionName: 'colorfulCircleMinDistance', }, propertyUniformMapping: { center: 'colorfulCircleCenters', diff --git a/src/drawables/shapes/inverted-tunnel-factory.ts b/src/drawables/shapes/inverted-tunnel-factory.ts index e0d3c4e..9fe2d01 100644 --- a/src/drawables/shapes/inverted-tunnel-factory.ts +++ b/src/drawables/shapes/inverted-tunnel-factory.ts @@ -36,7 +36,12 @@ export const InvertedTunnelFactory = ( uniform float fromRadii[INVERTED_TUNNEL_COUNT]; uniform float toRadii[INVERTED_TUNNEL_COUNT]; - uniform sampler2D noiseTexture; + // Other drawables share this declaration; the include guard keeps + // the combined shader from declaring it twice. + #ifndef NOISE_TEXTURE_DECLARED + #define NOISE_TEXTURE_DECLARED + uniform sampler2D noiseTexture; + #endif #ifdef WEBGL2_IS_AVAILABLE float invertedTunnelTerrain(float h) { diff --git a/src/drawables/shapes/noisy-polygon-factory.ts b/src/drawables/shapes/noisy-polygon-factory.ts index aba0d93..e021f2a 100644 --- a/src/drawables/shapes/noisy-polygon-factory.ts +++ b/src/drawables/shapes/noisy-polygon-factory.ts @@ -24,16 +24,25 @@ export const NoisyPolygonFactory = ( uniform float noisyPolygon${vertexCount}Lengths[NOISY_POLYGON${vertexCount}_COUNT]; uniform float noisyPolygon${vertexCount}Randoms[NOISY_POLYGON${vertexCount}_COUNT]; - uniform sampler2D noiseTexture; + // Other drawables (and other vertex-count variants of this one) + // share these declarations; the include guards keep the combined + // shader from declaring them twice. + #ifndef NOISE_TEXTURE_DECLARED + #define NOISE_TEXTURE_DECLARED + uniform sampler2D noiseTexture; + #endif - #ifdef WEBGL2_IS_AVAILABLE - float myTerrain(vec2 h) { - return texture(noiseTexture, h)[0] - 0.5; - } - #else - float myTerrain(vec2 h) { - return texture2D(noiseTexture, h)[0] - 0.5; - } + #ifndef MY_TERRAIN_DECLARED + #define MY_TERRAIN_DECLARED + #ifdef WEBGL2_IS_AVAILABLE + float myTerrain(vec2 h) { + return texture(noiseTexture, h)[0] - 0.5; + } + #else + float myTerrain(vec2 h) { + return texture2D(noiseTexture, h)[0] - 0.5; + } + #endif #endif vec2 noisyPolygon${vertexCount}LineDistance(vec2 target, vec2 from, vec2 to) {