Minimalist Sphere Impostor -- computing sphere radius in zdepth

100 Views Asked by At

I'm trying to code up a fast and minimalist sphere impostor-- the sphere doesn't need to be shaded or do anything but correct gl_FragDepth.

I have some code that's very close to working... cutting out everything but the key code:

vertex shader:

out_XYZ=float4(sphereCenter.xyz,1.)*sceneComboMatrix;
switch(gl_VertexID)
{
case 0:
    out_XYZ.xy+=vec2(radius,-radius);
    out_UV=float2(1.,-1.);
    break;
case 1:
    out_XYZ.xy+=vec2(-radius,-radius);
    out_UV=float2(-1.,-1.);
    break;
case 2:
    out_XYZ.xy+=vec2(radius,radius);
    out_UV=float2(1.,1.);
    break;
case 3:
    out_XYZ.xy+=vec2(-radius,radius);
    out_UV=float2(-1.,1.);
    break;
}

fragment shader:

float aLen2=dot(in_UV,in_UV);
float aL=inversesqrt(aLen2);
if (aL<1.) discard;
out_Color=float4(1.,0.,0.,1.);
float magicNumber=.0031f;
gl_FragDepth=gl_FragCoord.z-(sin(1.-(1./aL))*(3.14/2.)*magicNumber);

This produces the following: enter image description here

Not TOO bad... it works as a proof of concept. The issue is, my variable magicNumber above, which I simply fiddled around with, should be replaced with the radius of the sphere in zdepth.

How can I compute the size of the sphere's radius in terms of zdepth?

(A note: I don't need this to be hyperaccurate-- it's being used for some particles that can clip slightly wrong... but it does need to be more accurate than my screenshot above)

(EDIT----------) Using resources from Nicol Bolas, I wrote some code to attempt to get the difference in zdepth between the sphere's maximally close point ot the camera and the sphere's center. However, the result pushes the sphere VERY FAR toward the camera. Why doesn't this code give me the length of the sphere's radius in z-space (i.e. the difference in Z between the sphere's center and another point closer to the camera?)

vec4 aSPos=vec4(spherePos.xyz,1.)*sceneComboMatrix;
float aD1=aSPos.z/aSPos.w;
aSPos=vec4(spherePos.xyz+(normalTowardCamera.xyz*sphereRadius),1.)*sceneComboMatrix;
float aD2=aSPos.z/aSPos.w;
radiusLengthInZ=((gl_DepthRange.diff*(aD1-aD2))+gl_DepthRange.near+gl_DepthRange.far)/2.0;

0

There are 0 best solutions below