Ho problemi a far cambio di coordinate fra cartesiane e sferiche in uno shader su Unity, vi scrivo qui il codice strippato da tutto tranne il necessario:
Shader "Custom/BlindShader" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" { }
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert vertex:vert// tessellate:tessEdge
#pragma enable_d3d11_debug_symbols
#pragma target 3.0
struct Input {
float2 uv_MainTex;
};
sampler2D _MainTex;
static const float EPSILON = 1e-10;
static const float PI = 3.14159274;
float3 CartesianToSpherical(float3 cartesianCoordinates) {
if (cartesianCoordinates.x == 0)
cartesianCoordinates.x = EPSILON;
float radius = length(cartesianCoordinates);
float polar = atan(cartesianCoordinates.z / cartesianCoordinates.x);
if (cartesianCoordinates.x < 0)
polar += PI;
float elevation = asin(cartesianCoordinates.y / radius);
return (radius, polar, elevation);
}
float3 CartesianToSpherical(float3 center, float3 world) {
return CartesianToSpherical(world - center);
}
float3 SphericalToCartesian(float3 sphericalCoordinates) {
float a = sphericalCoordinates.x * cos(sphericalCoordinates.z);
return (
a * cos(sphericalCoordinates.y),
sphericalCoordinates.x * sin(sphericalCoordinates.z),
a * sin(sphericalCoordinates.y));
}
void vert (inout appdata_full v) {
float3 spherical;
float3 newSpherical;
float3 world;
float3 newWorld;
world = mul(unity_ObjectToWorld, v.vertex.xyz);
spherical = CartesianToSpherical(world);
newWorld = SphericalToCartesian(spherical);
v.vertex.xyz = mul(unity_WorldToObject, newWorld);
}
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
}
ENDCG
}
FallBack "Diffuse"
}
La cosa strana è che lo stesso identico codice trasformato in C# funziona su unity:
public Vector3 CartesianToSpherical(Vector3 cartesianCoordinates)
{
if (cartesianCoordinates.x == 0f)
cartesianCoordinates.x = Mathf.Epsilon;
float radius = cartesianCoordinates.magnitude;
float polar = Mathf.Atan(cartesianCoordinates.z / cartesianCoordinates.x);
if (cartesianCoordinates.x < 0f)
polar += Mathf.PI;
float elevation = Mathf.Asin(cartesianCoordinates.y / radius);
return new Vector3(radius, polar, elevation);
}
public Vector3 SphericalToCartesian(Vector3 sphericalCoordinates)
{
float a = sphericalCoordinates.x * Mathf.Cos(sphericalCoordinates.z);
return new Vector3(
a * Mathf.Cos(sphericalCoordinates.y),
sphericalCoordinates.x * Mathf.Sin(sphericalCoordinates.z),
a * Mathf.Sin(sphericalCoordinates.y));
}
Edit: non ho scritto il problema... comunque non funziona nulla con lo shader, tutti i vertici vanno a rotoli.