In general, you should never be creating a ValueProviderResult; you should be getting it from the dictionary provided by ModelBindingContext.ValueProvider. The reason that the culture is specified per-value isn't that textbox A has Culture A and textbox B has Culture B; it's that we need to know where the value came from.
Consider the case of ValueProvider["someDate"].ConvertTo(typeof(DateTime)). If someDate is specified in the URL (as it would be if it were a Routing parameter), this conversion should be done in a culture-invariant fashion. After all, the U in URL is for uniform. If I were in the U.S. and IMed my friend in the U.K. a URL containing a date, it shouldn't produce a 404 for him just because he's coming from a different country. However, if someDate were a form value (that is, we read it from Request.Form instead of Routing), you want to perform the conversion in a culture-aware fashion, because the user should be able to input form entries using his current locale's settings. In general, values from Routing and the query string (which together make the URL) are InvariantCulture, while values from Form are CurrentCulture.
OK - so this explains the CultureInfo, but what about the RawValue property? This has to do with the way in which we fetch values from the underlying mechanism - Routing, QueryString, or Form. Routing uses a RouteValueDictionary, a dictionary in which the entries are of type Object. QueryString and Form are internally NameValueCollections, and we call GetValues(), which returns a string array. This is what the RawValue returns - the result as given to us by the underlying mechanism, unmodified.
The RawValue and CultureInfo are both consumed by the ConvertTo() method, which can perform the conversion using the correct culture and give you the type you wanted. The AttemptedValue is only used by the validation framework; it's used for providing an error message if a submitted value is incorrect.