+ // form surface z and project texture onto it.
+ " float indentAmount = 1.0 / (1.0 - (z * uTextureDistortAmount));\n"
+ " vec2 distortedCoord = vCentredCoord * indentAmount;\n"
+
+ // Convert the rect coordinates in -1 to 1 range back to the original coordinates
+ " vec2 texCoord = vec2( ( (distortedCoord.x + 1.0)*(0.5) * (uEffectRegion.z - uEffectRegion.x) + uEffectRegion.x ), ( (distortedCoord.y + 1.0)*(0.5) * (uEffectRegion.w - uEffectRegion.y) + uEffectRegion.y ) ); \n"
+ " vec4 col = texture2D(sTexture, texCoord);\n"
+
+ // calc lighting
+ " float lighting = (dot(uDiffuseLight, norm) + uAmbientLight) * uLightMultiplier;\n"
+ " gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
+ "}\n"
+ "else\n"
+ "{\n"
+ " vec4 col = texture2D(sTexture, vTexCoord);\n"
+ " float lighting = (dot(uDiffuseLight, vec3(0.0, 0.0, 1.0)) + uAmbientLight) * uLightMultiplier;\n"
+ " gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
+ "}\n"
+ "}\n";
+
+ std::string fragmentSourceRectangular;
+ fragmentSourceRectangular = "precision mediump float;\n"
+
+ "uniform float uLightingIndentationAmount;\n"
+ "uniform float uTextureDistortAmount;\n"
+ "uniform vec3 uDiffuseLight;\n"
+ "uniform float uAmbientLight;\n"
+ "uniform float uLightMultiplier;\n"
+ "uniform float uInsideCircleSizeScale;\n"
+ "uniform float uRecipInsideCircleSizeScale;\n"
+ "uniform float uOutsideCircleDepth;\n"
+ "uniform float uRectangleSizeScale;\n"
+ "uniform vec4 uEffectRegion;\n"
+ "varying vec2 vCentredCoord;\n"
+
+ "const float PI = 3.1415927;\n"
+
+ "void main()\n"
+ "{\n"
+ // Apply distortion only if the pixel is within the rect specified
+ "if( (vTexCoord.x > uEffectRegion.x) && (vTexCoord.x < uEffectRegion.z) && (vTexCoord.y > uEffectRegion.y) && (vTexCoord.y < uEffectRegion.w) )\n"
+ "{ \n"
+ // get the rect coords to -1..1 range, i.e. circle centred around the center of the rect
+ " vec2 centredCoord = vCentredCoord;\n"
+ // clamp coords such that the circle is split into 4 pieces that lie in the corners of the actor. uRectangleScale is the distance along each axis from the centre
+ // of the actor, e.g. 0.5 is half way along an axis from centre to actor edge.
+ " vec2 clampedCoord;\n"
+ " if(centredCoord.x > 0.0)\n"
+ " {\n"
+ " if(centredCoord.x < uRectangleSizeScale)\n"
+ " {\n"
+ // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
+ " clampedCoord.x = 0.0;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ // we are outside rectangular region along this axis, so we want curvature.
+ " clampedCoord.x = smoothstep(0.0, 1.0, (centredCoord.x - uRectangleSizeScale) / (1.0 - uRectangleSizeScale));\n"
+ " }\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " if(centredCoord.x > -uRectangleSizeScale)\n"
+ " {\n"
+ // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
+ " clampedCoord.x = 0.0;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ // we are outside rectangular region along this axis, so we want curvature.
+ " clampedCoord.x = -smoothstep(0.0, 1.0, (centredCoord.x + uRectangleSizeScale) / (uRectangleSizeScale - 1.0));\n"
+ " }\n"
+ " }\n"
+ " if(centredCoord.y > 0.0)\n"
+ " {\n"
+ " if(centredCoord.y < uRectangleSizeScale)\n"
+ " {\n"
+ // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
+ " clampedCoord.y = 0.0;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ // we are outside rectangular region along this axis, so we want curvature.
+ " clampedCoord.y = smoothstep(0.0, 1.0, (centredCoord.y - uRectangleSizeScale) / (1.0 - uRectangleSizeScale));\n"
+ " }\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " if(centredCoord.y > -uRectangleSizeScale)\n"
+ " {\n"
+ // we are in a rectangular region along this axis, clamp coord to be same as centre pixel
+ " clampedCoord.y = 0.0;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ // we are outside rectangular region along this axis, so we want curvature.
+ " clampedCoord.y = -smoothstep(0.0, 1.0, (centredCoord.y + uRectangleSizeScale) / (uRectangleSizeScale - 1.0));\n"
+ " }\n"
+ " }\n"
+ // get coords in -PI..PI range, i.e. scale above circle for use by trig functions
+ " vec2 thetaCoord = clampedCoord * PI;\n"
+ // get a z value for the distorted surface in 0..1 range, using cos for a smooth curve (note, we ignore inside / outside circles since the difference isn't noticeable visually)
+ " vec2 cosThetaCoord = (cos(thetaCoord) * 0.5) + 0.5;\n"
+ " float z = cosThetaCoord.x * cosThetaCoord.y;\n"
+ // find a coordinate representing distance from circle centre, such that we split into inside / outside circles that can have different gradients / normals
+ " float realDistFromCentre = length(thetaCoord);\n"
+ " realDistFromCentre = min(PI, realDistFromCentre);\n" // clamp corners of square to vertical normal
+ " float distFromCentre;\n"
+ " if(realDistFromCentre <= PI * uInsideCircleSizeScale)\n"
+ " {\n"
+ " distFromCentre = realDistFromCentre * uRecipInsideCircleSizeScale * (PI - (uOutsideCircleDepth * PI)) / PI;\n" // inside circle indent, up to outline depth
+ " }\n"
+ " else\n"
+ " {\n"
+ " distFromCentre = mix(PI - (uOutsideCircleDepth * PI), PI, (realDistFromCentre - ( PI * uInsideCircleSizeScale)) / (PI - (PI * uInsideCircleSizeScale)));\n" // outside circle
+ " }\n"
+ // get the normal for the distorted surface, using the fact that the derivative of cos is -sin, finding tangent vector from slope and then normal by cross product...
+ " float sinThetaCoord = sin(distFromCentre) * uLightingIndentationAmount;\n" // slope, so tangent vec is (1.0, -sin)
+ // ...2D normal vector along distFromCentre vec is (sin, 1.0), convert to components in 3D.
+ " vec3 norm = normalize(vec3(thetaCoord.x * sinThetaCoord, thetaCoord.y * sinThetaCoord, 1.0));\n"
+ // form surface z and project texture onto it.
+ " float indentAmount = 1.0 / (1.0 - (z * uTextureDistortAmount));\n"
+ " vec2 distortedCoord = centredCoord * indentAmount;\n"
+ // Convert the rect coordinates in -1 to 1 range back to the original coordinates
+ " vec2 texCoord = vec2( ( (distortedCoord.x + 1.0)/(2.0) * (uEffectRegion.z - uEffectRegion.x) + uEffectRegion.x ), ( (distortedCoord.y + 1.0)/(2.0) * (uEffectRegion.w - uEffectRegion.y) + uEffectRegion.y ) );\n"
+ " vec4 col = texture2D(sTexture, texCoord);\n"
+ // calc lighting
+ " float lighting = (dot(uDiffuseLight, norm) + uAmbientLight) * uLightMultiplier;\n"
+ // output col = image * light
+ // use the lighting value for colors only
+ " gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
+
+ "}\n"
+ "else\n"
+ "{\n"
+ " vec4 col = texture2D(sTexture, vTexCoord);\n"
+ " float lighting = (dot(uDiffuseLight, vec3(0.0, 0.0, 1.0)) + uAmbientLight) * uLightMultiplier;\n"
+ " gl_FragColor = vec4(col.rgb * uColor.rgb * lighting, col.a * uColor.a);\n"
+ "} \n"
+ "}\n";
+
+
+ //////////////////////////////////////
+ // Create shader effectCreateSoftButtonEffect
+ //
+ //
+
+ ShaderEffect shader;
+ switch(type)