diff options
author | 2014-09-23 09:50:21 -0700 | |
---|---|---|
committer | 2014-09-23 09:50:21 -0700 | |
commit | b0a8a377f832c59cee939ad721e1f87d378b7142 (patch) | |
tree | 7edeac33c817af28d73f3fbe1b31776ac34e8773 /src/gpu/GrOvalRenderer.cpp | |
parent | e51ac563de24ed4b25fde97c225580a30a55e9ca (diff) |
Patch to create a distinct geometry processor. The vast majority of this patch
is just a rename. The meat is in GrGeometryProcessor, GrProcessor,
GrGL*Processor, GrProcessorStage, Gr*BackendProcessorFactory,
GrProcessUnitTestFactory, and the builders
BUG=skia:
R=bsalomon@google.com
Author: joshualitt@chromium.org
Review URL: https://codereview.chromium.org/582963002
Diffstat (limited to 'src/gpu/GrOvalRenderer.cpp')
-rw-r--r-- | src/gpu/GrOvalRenderer.cpp | 190 |
1 files changed, 96 insertions, 94 deletions
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index ae992ec4fb..4ae0ebc7ef 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -8,11 +8,11 @@ #include "GrOvalRenderer.h" #include "gl/builders/GrGLFullProgramBuilder.h" -#include "gl/GrGLEffect.h" +#include "gl/GrGLProcessor.h" #include "gl/GrGLSL.h" #include "gl/GrGLGeometryProcessor.h" -#include "GrEffect.h" -#include "GrTBackendEffectFactory.h" +#include "GrProcessor.h" +#include "GrTBackendProcessorFactory.h" #include "GrDrawState.h" #include "GrDrawTarget.h" @@ -22,7 +22,7 @@ #include "SkStrokeRec.h" #include "SkTLazy.h" -#include "effects/GrGeometryProcessor.h" +#include "GrGeometryProcessor.h" #include "effects/GrRRectEffect.h" namespace { @@ -62,9 +62,9 @@ inline bool circle_stays_circle(const SkMatrix& m) { class CircleEdgeEffect : public GrGeometryProcessor { public: - static GrEffect* Create(bool stroke) { - GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true)); - GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false)); + static GrGeometryProcessor* Create(bool stroke) { + GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCircleStrokeEdge, CircleEdgeEffect, (true)); + GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gCircleFillEdge, CircleEdgeEffect, (false)); if (stroke) { gCircleStrokeEdge->ref(); @@ -82,8 +82,8 @@ public: const GrShaderVar& inCircleEdge() const { return fInCircleEdge; } - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { - return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance(); + virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { + return GrTBackendGeometryProcessorFactory<CircleEdgeEffect>::getInstance(); } virtual ~CircleEdgeEffect() {} @@ -92,26 +92,26 @@ public: inline bool isStroked() const { return fStroke; } - class GLEffect : public GrGLGeometryProcessor { + class GLProcessor : public GrGLGeometryProcessor { public: - GLEffect(const GrBackendEffectFactory& factory, const GrEffect&) + GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&) : INHERITED (factory) {} virtual void emitCode(GrGLFullProgramBuilder* builder, - const GrEffect& effect, - const GrEffectKey& key, + const GrGeometryProcessor& geometryProcessor, + const GrProcessorKey& key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - const CircleEdgeEffect& circleEffect = effect.cast<CircleEdgeEffect>(); + const CircleEdgeEffect& circleEffect = geometryProcessor.cast<CircleEdgeEffect>(); const char *vsName, *fsName; builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName); GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder();; vsBuilder->codeAppendf("\t%s = %s;\n", vsName, circleEffect.inCircleEdge().c_str()); - GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); + GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName); fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName); if (circleEffect.isStroked()) { @@ -123,13 +123,13 @@ public: (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str()); } - static void GenKey(const GrEffect& effect, const GrGLCaps&, - GrEffectKeyBuilder* b) { - const CircleEdgeEffect& circleEffect = effect.cast<CircleEdgeEffect>(); + static void GenKey(const GrProcessor& processor, const GrGLCaps&, + GrProcessorKeyBuilder* b) { + const CircleEdgeEffect& circleEffect = processor.cast<CircleEdgeEffect>(); b->add32(circleEffect.isStroked()); } - virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVERRIDE {} + virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {} private: typedef GrGLGeometryProcessor INHERITED; @@ -145,7 +145,7 @@ private: fStroke = stroke; } - virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { + virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { const CircleEdgeEffect& cee = other.cast<CircleEdgeEffect>(); return cee.fStroke == fStroke; } @@ -153,17 +153,17 @@ private: const GrShaderVar& fInCircleEdge; bool fStroke; - GR_DECLARE_EFFECT_TEST; + GR_DECLARE_GEOMETRY_PROCESSOR_TEST; typedef GrGeometryProcessor INHERITED; }; -GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); +GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); -GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random, - GrContext* context, - const GrDrawTargetCaps&, - GrTexture* textures[]) { +GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, + GrContext* context, + const GrDrawTargetCaps&, + GrTexture* textures[]) { return CircleEdgeEffect::Create(random->nextBool()); } @@ -179,9 +179,9 @@ GrEffect* CircleEdgeEffect::TestCreate(SkRandom* random, class EllipseEdgeEffect : public GrGeometryProcessor { public: - static GrEffect* Create(bool stroke) { - GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); - GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false)); + static GrGeometryProcessor* Create(bool stroke) { + GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseStrokeEdge, EllipseEdgeEffect, (true)); + GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseFillEdge, EllipseEdgeEffect, (false)); if (stroke) { gEllipseStrokeEdge->ref(); @@ -197,8 +197,8 @@ public: *validFlags = 0; } - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { - return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance(); + virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { + return GrTBackendGeometryProcessorFactory<EllipseEdgeEffect>::getInstance(); } virtual ~EllipseEdgeEffect() {} @@ -210,19 +210,19 @@ public: inline bool isStroked() const { return fStroke; } - class GLEffect : public GrGLGeometryProcessor { + class GLProcessor : public GrGLGeometryProcessor { public: - GLEffect(const GrBackendEffectFactory& factory, const GrEffect&) + GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&) : INHERITED (factory) {} virtual void emitCode(GrGLFullProgramBuilder* builder, - const GrEffect& effect, - const GrEffectKey& key, + const GrGeometryProcessor& geometryProcessor, + const GrProcessorKey& key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - const EllipseEdgeEffect& ellipseEffect = effect.cast<EllipseEdgeEffect>(); + const EllipseEdgeEffect& ellipseEffect = geometryProcessor.cast<EllipseEdgeEffect>(); const char *vsOffsetName, *fsOffsetName; const char *vsRadiiName, *fsRadiiName; @@ -237,7 +237,7 @@ public: vsBuilder->codeAppendf("%s = %s;", vsRadiiName, ellipseEffect.inEllipseRadii().c_str()); // for outer curve - GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); + GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName); fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n"); fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fsRadiiName); @@ -260,13 +260,13 @@ public: (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str()); } - static void GenKey(const GrEffect& effect, const GrGLCaps&, - GrEffectKeyBuilder* b) { - const EllipseEdgeEffect& ellipseEffect = effect.cast<EllipseEdgeEffect>(); + static void GenKey(const GrProcessor& processor, const GrGLCaps&, + GrProcessorKeyBuilder* b) { + const EllipseEdgeEffect& ellipseEffect = processor.cast<EllipseEdgeEffect>(); b->add32(ellipseEffect.isStroked()); } - virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVERRIDE { + virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE { } private: @@ -286,7 +286,7 @@ private: fStroke = stroke; } - virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { + virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { const EllipseEdgeEffect& eee = other.cast<EllipseEdgeEffect>(); return eee.fStroke == fStroke; } @@ -295,17 +295,17 @@ private: const GrShaderVar& fInEllipseRadii; bool fStroke; - GR_DECLARE_EFFECT_TEST; + GR_DECLARE_GEOMETRY_PROCESSOR_TEST; typedef GrGeometryProcessor INHERITED; }; -GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); +GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); -GrEffect* EllipseEdgeEffect::TestCreate(SkRandom* random, - GrContext* context, - const GrDrawTargetCaps&, - GrTexture* textures[]) { +GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, + GrContext* context, + const GrDrawTargetCaps&, + GrTexture* textures[]) { return EllipseEdgeEffect::Create(random->nextBool()); } @@ -324,10 +324,10 @@ class DIEllipseEdgeEffect : public GrGeometryProcessor { public: enum Mode { kStroke = 0, kHairline, kFill }; - static GrEffect* Create(Mode mode) { - GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStroke)); - GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHairline)); - GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill)); + static GrGeometryProcessor* Create(Mode mode) { + GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStroke)); + GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHairline)); + GR_CREATE_STATIC_GEOMETRY_PROCESSOR(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill)); if (kStroke == mode) { gEllipseStrokeEdge->ref(); @@ -346,8 +346,8 @@ public: *validFlags = 0; } - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { - return GrTBackendEffectFactory<DIEllipseEdgeEffect>::getInstance(); + virtual const GrBackendGeometryProcessorFactory& getFactory() const SK_OVERRIDE { + return GrTBackendGeometryProcessorFactory<DIEllipseEdgeEffect>::getInstance(); } virtual ~DIEllipseEdgeEffect() {} @@ -359,19 +359,20 @@ public: inline Mode getMode() const { return fMode; } - class GLEffect : public GrGLGeometryProcessor { + class GLProcessor : public GrGLGeometryProcessor { public: - GLEffect(const GrBackendEffectFactory& factory, const GrEffect&) + GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&) : INHERITED (factory) {} virtual void emitCode(GrGLFullProgramBuilder* builder, - const GrEffect& effect, - const GrEffectKey& key, + const GrGeometryProcessor& geometryProcessor, + const GrProcessorKey& key, const char* outputColor, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) SK_OVERRIDE { - const DIEllipseEdgeEffect& ellipseEffect = effect.cast<DIEllipseEdgeEffect>(); + const DIEllipseEdgeEffect& ellipseEffect = + geometryProcessor.cast<DIEllipseEdgeEffect>(); const char *vsOffsetName0, *fsOffsetName0; builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0", @@ -386,7 +387,7 @@ public: vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1, ellipseEffect.inEllipseOffsets1().c_str()); - GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); + GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); SkAssertResult(fsBuilder->enableFeature( GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); // for outer curve @@ -427,14 +428,14 @@ public: (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str()); } - static void GenKey(const GrEffect& effect, const GrGLCaps&, - GrEffectKeyBuilder* b) { - const DIEllipseEdgeEffect& ellipseEffect = effect.cast<DIEllipseEdgeEffect>(); + static void GenKey(const GrProcessor& processor, const GrGLCaps&, + GrProcessorKeyBuilder* b) { + const DIEllipseEdgeEffect& ellipseEffect = processor.cast<DIEllipseEdgeEffect>(); b->add32(ellipseEffect.getMode()); } - virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVERRIDE { + virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE { } private: @@ -454,7 +455,7 @@ private: fMode = mode; } - virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { + virtual bool onIsEqual(const GrProcessor& other) const SK_OVERRIDE { const DIEllipseEdgeEffect& eee = other.cast<DIEllipseEdgeEffect>(); return eee.fMode == fMode; } @@ -463,17 +464,17 @@ private: const GrShaderVar& fInEllipseOffsets1; Mode fMode; - GR_DECLARE_EFFECT_TEST; + GR_DECLARE_GEOMETRY_PROCESSOR_TEST; typedef GrGeometryProcessor INHERITED; }; -GR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect); +GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect); -GrEffect* DIEllipseEdgeEffect::TestCreate(SkRandom* random, - GrContext* context, - const GrDrawTargetCaps&, - GrTexture* textures[]) { +GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, + GrContext* context, + const GrDrawTargetCaps&, + GrTexture* textures[]) { return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); } @@ -518,7 +519,7 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bo // position + edge extern const GrVertexAttrib gCircleVertexAttribs[] = { {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, - {kVec4f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding} + {kVec4f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding} }; void GrOvalRenderer::drawCircle(GrDrawTarget* target, @@ -571,8 +572,8 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target, } } - GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0); - drawState->setGeometryProcessor(effect)->unref(); + GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0); + drawState->setGeometryProcessor(gp)->unref(); // The radii are outset for two reasons. First, it allows the shader to simply perform // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the @@ -616,15 +617,15 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target, // position + offset + 1/radii extern const GrVertexAttrib gEllipseVertexAttribs[] = { {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, - {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}, - {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kEffect_GrVertexAttribBinding} + {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}, + {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding} }; // position + offsets extern const GrVertexAttrib gDIEllipseVertexAttribs[] = { {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding}, - {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}, - {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kEffect_GrVertexAttribBinding}, + {kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}, + {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kGeometryProcessor_GrVertexAttribBinding}, }; bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, @@ -710,10 +711,10 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); - GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly && - innerXRadius > 0 && innerYRadius > 0); + GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly && + innerXRadius > 0 && innerYRadius > 0); - drawState->setGeometryProcessor(effect)->unref(); + drawState->setGeometryProcessor(gp)->unref(); // Compute the reciprocals of the radii here to save time in the shader SkScalar xRadRecip = SkScalarInvert(xRadius); @@ -827,9 +828,9 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices()); - GrEffect* effect = DIEllipseEdgeEffect::Create(mode); + GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode); - drawState->setGeometryProcessor(effect)->unref(); + drawState->setGeometryProcessor(gp)->unref(); // This expands the outer rect so that after CTM we end up with a half-pixel border SkScalar a = vm[SkMatrix::kMScaleX]; @@ -920,14 +921,15 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrContext* context, bool u return false; } } - GrEffectEdgeType edgeType = applyAA ? kInverseFillAA_GrEffectEdgeType : - kInverseFillBW_GrEffectEdgeType; - GrEffect* effect = GrRRectEffect::Create(edgeType, *inner); - if (NULL == effect) { + GrPrimitiveEdgeType edgeType = applyAA ? + kInverseFillAA_GrProcessorEdgeType : + kInverseFillBW_GrProcessorEdgeType; + GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); + if (NULL == fp) { return false; } are.set(target->drawState()); - target->drawState()->addCoverageEffect(effect)->unref(); + target->drawState()->addCoverageProcessor(fp)->unref(); } SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); @@ -942,9 +944,9 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrContext* context, bool u return false; } } - GrEffectEdgeType edgeType = applyAA ? kFillAA_GrEffectEdgeType : - kFillBW_GrEffectEdgeType; - GrEffect* effect = GrRRectEffect::Create(edgeType, *outer); + GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : + kFillBW_GrProcessorEdgeType; + GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); if (NULL == effect) { return false; } @@ -955,7 +957,7 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrContext* context, bool u if (!avmr.setIdentity(target->drawState())) { return false; } - target->drawState()->addCoverageEffect(effect)->unref(); + target->drawState()->addCoverageProcessor(effect)->unref(); SkRect bounds = outer->getBounds(); if (applyAA) { bounds.outset(SK_ScalarHalf, SK_ScalarHalf); @@ -1075,7 +1077,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool us isStrokeOnly = (isStrokeOnly && innerRadius >= 0); - GrEffect* effect = CircleEdgeEffect::Create(isStrokeOnly); + GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly); drawState->setGeometryProcessor(effect)->unref(); // The radii are outset for two reasons. First, it allows the shader to simply perform @@ -1178,7 +1180,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool us } EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices()); - GrEffect* effect = EllipseEdgeEffect::Create(isStrokeOnly); + GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly); drawState->setGeometryProcessor(effect)->unref(); // Compute the reciprocals of the radii here to save time in the shader |