使用GLSL将球体变形为立方体并将球体变形为球体

我正在与石英composer phpGLSL开始。 我有一个粒子系统的补丁,其中每个粒子映射到一个具有混合值的球体。 随着blend=0粒子处于随机位置, blend=1粒子在球体中。 代码在这里:

 vec3 sphere(vec2 domain) { vec3 range; range.x = radius * cos(domain.y) * sin(domain.x); range.y = radius * sin(domain.y) * sin(domain.x); range.z = radius * cos(domain.x); return range; } // in main: vec2 p0 = gl_Vertex.xy * twopi; vec3 normal = sphere(p0);; vec3 r0 = radius * normal; vec3 vertex = r0; normal = normal * blend + gl_Normal * (1.0 - blend); vertex = vertex * blend + gl_Vertex.xyz * (1.0 - blend); 

如果blend=0我希望粒子在一个立方体上

我试图find,但我不知道立方体的一些参数方程。 也许这是不正确的方式?

编辑:源代码着色器代码testing,更新和工程…

变茶壶到立方体

还有video…

一旦你使用三维坐标而不是2D来对立方体进行采样,这是可能的(但不是参数:))。

第一个理论:

使用normalize(GL_Vertex – cubeOrigin)作为采样向量。

您必须知道立方体顶点属于哪个面。 它是抽样vector中最大的组成部分。

一旦你有脸,你可以指定脸部正常。 计算面法线和采样向量之间的角度。 使用正弦律来从立方体原点(中间)获得空间点的距离。 乘以这个距离与正常,你得到它:)

 // this code sucks for shader ... it would be slow it is written to be clear not optimal. uniform int timer; //return face's ID based on sampling vector int face(vec3 coord) { if((abs(coord.x) > abs(coord.y)) && (abs(coord.x) > abs(coord.z))) { if (coord.x > 0) return 0; else return 1; } if( abs(coord.y) > abs(coord.z)) { if (coord.y > 0) return 2; else return 3; } if (coord.z > 0) return 4; return 5; } vec3 cube(vec3 position,vec3 cubeOrigin) { int CUBE_SIZE = 2; vec3 coord = normalize(position - cubeOrigin); int face = face(coord); vec3 faceNormal = vec3(0); switch (face) { case 0: faceNormal = vec3(1,0,0); break; case 1: faceNormal = vec3(-1,0,0); break; case 2: faceNormal = vec3(0,1,0); break; case 3: faceNormal = vec3(0,-1,0); break; case 4: faceNormal = vec3(0,0,1); break; case 5: faceNormal = vec3(0,0,-1); break; } float gamma = acos (dot(faceNormal,coord)); float alfa = 3.14 - 1.57 - gamma; //there is no PI or HALF_PI in glsl you have to define it on your own. //this is little hard stuff. You want to know length from origin to place on cube. It is simple triangle and can be solved by law of sines. //It should be multiplied with sin(HALF_PI) but it is 1. float posFactor = (CUBE_SIZE/2.0)/sin(alfa) ; return (cubeOrigin + coord * posFactor); } void main(void) { vec3 transformed = cube(gl_Vertex.xyz,vec3(0.0,0.0,0.0)); vec4 cubetrans = vec4 (transformed,1.0); gl_Position = mix(gl_ModelViewProjectionMatrix * cubetrans,gl_ModelViewProjectionMatrix * gl_Vertex,timer/200.0); gl_FrontColor = gl_Color; }