MaplyShader

@interface MaplyShader : NSObject
The shader is a direct interface to OpenGL ES 2.0 shader language.

You can set your own shader programs in the toolkit!  Yeah, that's as complex as it sounds.

The underyling toolkit makes a distinction between the name of the shader and the scene name.  The scene name is used as a way to replace the default shaders we use for triangles and lines.  This would let you replace the shaders you're already using with your own.  See the addShaderProgram:sceneName: method in the MaplyBaseViewController.

You can also add your own shader and hook it up to any features that can call out a specific shader, such as the MaplyQuadImageTilesLayer.

When writing a new shader, go take a look at DefaultShaderPrograms.mm, particularly the vertexShaderTri and fragmentShaderTri.  The documentation here is for the uniforms and attributes the system is going to hook up for you.  All of these are optional, but obviously nothing much will happen if you don't use the vertices.

Uniform Values

These are uniform values provided to each shader, if requested.

|uniform|type|description| |:——|:—|:———-| |u_mvpMatrix|mat4| The model/view/projection matrix. Shaders typically run vertices through this. | |u_mvMatrix|mat4| The model/view matrix. Less comonly used. | |u_mvNormalMatrix|mat4| The model/view matrix for normals. A shader typically uses this when we want view dependent lighting. | |u_fade|float| Available in regular drawables, but not yet in big drawables (e.g. atlases). This is intended to fade geometry in and out over time. | |u_interp|float| If we’re doing multiple textures, this is how to interpolate them. | |u_numLights|int| The number of active lights to use. | |light[8]|directional_light| A data structure for each active light. See the table below. | |material|material_properties| Material information used to calculate lighting. See the table below. | |u_hasTexture|bool| True if there’s a texture available to fetch data from. | |s_baseMapX|sampler2D| s_baseMap0, s_baseMap1 and so forth are references to texture data. |

Material properties

These are the fields for the material properties.

field type description
ambient vec4 The ambient value for the material. Shaders typically multiply by this value when calculating ambient lighting.
diffuse vec4 The diffuse value for the material. Shaders typically multiply by this value when calculating diffuse lighting.
specular vec4 Not currently used.
specular_exponent float Not currently used.

Light properties

These are the fields for each individual light.

|field|type|description| |:—-|:—|:———-| |direction|vec3| The light’s direction, used in diffuse lighting. | |halfplane|vec3| This would be used in specular lighting. | |ambient|vec4| The ambient value of the light. | |diffuse|vec4| The diffuse value of the light. | |specular|vec4| Not currently used. | |viewdepend|float| If greater than 0.0, the shader should run each normal through the u_mvNormalMatrix. |

Attributes

These are the per vertex attributes provided to each vertex shader.

|field|type|description| |:—-|:—|:———-| |a_position|vec3| The position in display space for a vertex. Shaders typically multiply this by u_mvpMatrix. | |a_texCoord0|vec2| If textures are present, this is the texture coordinate for the first one. | |a_texCoord1|vec2| If two textures are present, this is the texture coordinate for the second. | |a_color|vec4| An RGBA color for the vertex. | |a_normal|vec3| A normal in display space. This is used purely for lighting and often run through u_mvNormalMatrix. | |a_elev|float| An optional elevation value provided by the MaplyQuadImageTiles layer. You can use it to do elevation dependent shading. |

  • Initialize with the file names for the shader program.

    See initWithName:vertex:fragment:viewC: for more details on how this works.

    Declaration

    Objective-C

    - (nullable instancetype)initWithName:(NSString *_Nonnull)name
                               vertexFile:(NSString *_Nonnull)vertexFileName
                             fragmentFile:(NSString *_Nonnull)fragFileName
                                    viewC:(MaplyBaseViewController *_Nonnull)
                                              baseViewC;

    Swift

    init?(name: String, vertexFile vertexFileName: String, fragmentFile fragFileName: String, viewC baseViewC: MaplyBaseViewController)

    Parameters

    name

    The name of the shader program. Used for identification and sometimes lookup.

    vertexFileName

    The file (in the bundle) containing the vertex shader.

    fragFileName

    The file (in the bundle) containing the fragment shader.

    baseViewC

    The view controller where we’ll register the new shader.

    Return Value

    Returns a shader program if it succeeded. It may not work, however, so call valid first.

  • Initialize with the shader programs tied to a particular view controller.

    This initializer will parse the given shader program, link it and return a MaplyShader if it succeeded. It will tie that shader in to the given view controller (and really, it’s renderer). You can only use that shader in that view controller.

    Declaration

    Objective-C

    - (nullable instancetype)initWithName:(NSString *_Nonnull)name
                                   vertex:(NSString *_Nonnull)vertexProg
                                 fragment:(NSString *_Nonnull)fragProg
                                    viewC:(MaplyBaseViewController *_Nonnull)
                                              baseViewC;

    Swift

    init?(name: String, vertex vertexProg: String, fragment fragProg: String, viewC baseViewC: MaplyBaseViewController)

    Parameters

    name

    The name of the shader program. Used for identification and sometimes lookup.

    vertexProg

    The string containing the full vertex program.

    fragProg

    The string containing the full fragment program.

    baseViewC

    The view controller where we’ll register the new shader.

    Return Value

    Returns a shader program if it succeeded. IT may not work, however, so call valid first.

  • Name of the shader program.

    This is the name passed in to the init call. You can search by this name in some circumstances.

    Declaration

    Objective-C

    @property (readwrite, strong, nonatomic) NSString *_Nullable name;

    Swift

    var name: String? { get set }
  • Add a texture tied to the given attribute name.

    Shaders can have a variety of attributes passed to them. This is incompletely implemented and documented. In this particular case we add the given image, convert it to a texture and tie it to the shader attribute name.

    Declaration

    Objective-C

    - (void)addTextureNamed:(NSString *_Nonnull)shaderAttrName image:(id)image;

    Swift

    func addTextureNamed(_ shaderAttrName: String, image: Any!)

    Parameters

    shaderAttrName

    The name of the attribute in the shader. This should be compatible with a texture.

    image

    The UIImage we’ll convert to a texture and pass in. This UIImage will be tracked by the view controller and disposed of when we’re finished with it.

  • Add a texture tied to the given attribute name.

    Shaders can have a variety of attributes passed to them. This is incompletely implemented and documented. In this particular case we add the given image, convert it to a texture and tie it to the shader attribute name.

    Key Type Description
    kMaplyTexFormat NSNumber The texture format to use for the image. Consult addTexture:imageFormat:wrapFlags:mode: for a list. Default is MaplyImageIntRGBA.
    kMaplyTexMinFilter NSNumber Filter to use for minification. This can be kMaplyMinFilterNearest or kMaplyMinFilterLinear. Default is kMaplyMinFilterLinear.
    kMaplyTexMagFilter NSNumber Filter to use for magnification. This can be kMaplyMinFilterNearest or kMaplyMinFilterLinear. Default is kMaplyMinFilterLinear.
    kMaplyTexWrapX NSNumber boolean Texture wraps in x direction. Off by default.
    kMaplyTexWrapY NSNumber boolean Texture wraps in y direction. Off by default.
    kMaplyTexAtlas NSNumber boolean If set, the texture goes into an appropriate atlas. If not set, it’s a standalone texture (default).

    Declaration

    Objective-C

    - (void)addTextureNamed:(NSString *_Nonnull)shaderAttrName
                      image:(id)image
                       desc:(NSDictionary *_Nullable)desc;

    Swift

    func addTextureNamed(_ shaderAttrName: String, image: Any!, desc: [AnyHashable : Any]?)

    Parameters

    shaderAttrName

    The name of the attribute in the shader. This should be compatible with a texture.

    image

    The UIImage we’ll convert to a texture and pass in. This UIImage will be tracked by the view controller and disposed of when we’re finished with it.

    desc

    A description dictionary controlling how the image is converted to a texture and represented in the system.

  • Set a float uniform in the shader with the given name.

    Declaration

    Objective-C

    - (_Bool)setUniformFloatNamed:(NSString *_Nonnull)uniName val:(float)val;

    Swift

    func setUniformFloatNamed(_ uniName: String, val: Float) -> Bool

    Return Value

    Returns true if there was such a uniform, false otherwise.

  • Set an integer uniform in the shader with the given name.

    Declaration

    Objective-C

    - (_Bool)setUniformIntNamed:(NSString *_Nonnull)uniName val:(int)val;

    Swift

    func setUniformIntNamed(_ uniName: String, val: Int32) -> Bool

    Return Value

    Returns true if there was such a uniform, false otherwise.

  • Set a 2 component float uniform in the shader with the given name.

    Declaration

    Objective-C

    - (_Bool)setUniformVector2Named:(NSString *_Nonnull)uniName
                                  x:(float)x
                                  y:(float)y;

    Swift

    func setUniformVector2Named(_ uniName: String, x: Float, y: Float) -> Bool

    Return Value

    Returns true if there was such a uniform, false otherwise.

  • Set a 3 component float uniform in the shader with the given name.

    Declaration

    Objective-C

    - (_Bool)setUniformVector3Named:(NSString *_Nonnull)uniName
                                  x:(float)x
                                  y:(float)y
                                  z:(float)z;

    Swift

    func setUniformVector3Named(_ uniName: String, x: Float, y: Float, z: Float) -> Bool

    Return Value

    Returns true if there was such a uniform, false otherwise.

  • Set a 4 component float uniform in the shader with the given name.

    Declaration

    Objective-C

    - (_Bool)setUniformVector4Named:(NSString *_Nonnull)uniName
                                  x:(float)x
                                  y:(float)y
                                  z:(float)z
                                  w:(float)w;

    Swift

    func setUniformVector4Named(_ uniName: String, x: Float, y: Float, z: Float, w: Float) -> Bool

    Return Value

    Returns true if there was such a uniform, false otherwise.

  • Set a 4 component float uniform in the shader with the given name at the given index

    Declaration

    Objective-C

    - (_Bool)setUniformVector4Named:(NSString *_Nonnull)uniName
                                  x:(float)x
                                  y:(float)y
                                  z:(float)z
                                  w:(float)w
                              index:(int)which;

    Swift

    func setUniformVector4Named(_ uniName: String, x: Float, y: Float, z: Float, w: Float, index which: Int32) -> Bool

    Return Value

    Returns true if there was such a uniform, false otherwise.

  • Check if the shader is valid.

    The shader setup can fail in a number of ways. Check this after creating the shader to see if it succeded. If not, look to getError to see why.

    Declaration

    Objective-C

    - (_Bool)valid;

    Swift

    func valid() -> Bool
  • Return the compilation error if there was one.

    Shader construction can fail in a number of interesting ways. Call valid to see if it did fail, and then call this method to see why.

    Declaration

    Objective-C

    - (NSString *_Nullable)getError;

    Swift

    func getError() -> String?