how to draw sphere in 3d

Rendering a Sphere on a Quad

Making the Sphere Impostor Feel More Competent

My First Sphere Impostor

            float sphIntersect( float3 ro, float3 rd, float4 sph )
{
float3 oc = ro - sph.xyz;
float b = dot( oc, rd );
float c = dot( oc, oc ) - sph.w*sph.w;
float h = b*b - c;
if( h<0.0 ) render -1.0;
h = sqrt( h );
return -b - h;
}
            float3 worldPos = mul(unity_ObjectToWorld, v.vertex);
float3 rayDir = _WorldSpaceCameraPos.xyz - worldPos;

Depth Finder

It looks like a sphere, only it'south actually a cube.

A very round cube. Make all the boy cubes become *whaaah!*.

Texturing a Sphere

Equirectangular UVs

            float2 uv = float2(
// atan returns a value between -pi and pi
// so we split up past pi * 2 to get -0.5 to 0.5
atan2(normal.z, normal.x) / (UNITY_PI * 2.0),
// acos returns 0.0 at the top, pi at the lesser
// so nosotros flip the y to align with Unity'southward OpenGL mode
// texture UVs so 0.0 is at the lesser
acos(-normal.y) / UNITY_PI
);
fixed4 col = tex2D(_MainTex, uv);

Earth the terminal frontier.

Is that the Greenwich Mean Line?

Unseamly

            // -0.five to 0.v range
float phi = atan2(worldNormal.z, worldNormal.x) / (UNITY_PI * 2.0);
// 0.0 to ane.0 range
float phi_frac = frac(phi);
float2 uv = float2(
// uses a small bias to adopt the commencement 'UV set up'
fwidth(phi) < fwidth(phi_frac) - 0.001 ? phi : phi_frac,
acos(-worldNormal.y) / UNITY_PI
);

I promise it's not hiding on the other side.

Crunchy Edges (aka Derivatives Strike Over again)

Crunchy "outline" on the impostor.

The Hidden UV Seam

            // same sphere intersection function
bladder rayHit = sphIntersect(rayOrigin, rayDir, float4(0,0,0,0.5));
// clip if -i.0 to hide sphere on miss
clip(rayHit);
// dot product gets ray length at position closest to sphere
rayHit = rayHit < 0.0 ? dot(rayDir, spherePos - rayOrigin) : rayHit;

No longer seamful.

Object Calibration & Rotation

            // vertex shader
float3 worldSpaceRayDir = worldPos - _WorldSpaceCameraPos.xyz;
// only desire to rotate and scale the dir vector, so west = 0
o.rayDir = mul(unity_WorldToObject, float4(worldSpaceRayDir, 0.0));
// need to utilize total transform to the origin vector
o.rayOrigin = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos.xyz, i.0));
// fragment shader
float3 spherePos = float3(0,0,0);
            // now gets an object space surface position instead of globe space
float3 objectSpacePos = rayDir * rayHit + rayOrigin;
// withal need to normalize this in object infinite for the UVs
float3 objectSpaceNormal = normalize(objectSpacePos);
float3 worldNormal = UnityObjectToWorldNormal(objectSpaceNormal);
float3 worldPos = mul(unity_ObjectToWorld, float4(objectSpacePos, ane.0));

Big, little, and terrible sandwich Earths.

Using a Quad

Billboard Shader

View Facing Billboard

            // go object's world space pivot from the transform matrix
float3 worldSpacePivot = unity_ObjectToWorld._m03_m13_m23;
// transform into view infinite
float3 viewSpacePivot = mul(UNITY_MATRIX_V, float4(worldSpacePivot, 1.0));
// object space vertex position + view pivot = billboarded quad
float3 viewSpacePos = 5.vertex.xyz + viewSpacePivot;
// calculate the object space ray dir from the view infinite position
o.rayDir = mul(unity_WorldToObject,
mul(UNITY_MATRIX_I_V, float4(viewSpacePos, 0.0))
);
// use project matrix to get clip space position
o.pos = mul(UNITY_MATRIX_P, float4(viewSpacePos, one.0));

Thinking too far outside the box.

Creative person's Recreation of the Criminal offence Scene

Camera Facing Billboard

            float3 worldSpacePivot = unity_ObjectToWorld._m03_m13_m23;            // get-go betwixt pivot and photographic camera
float3 worldSpacePivotToCamera = _WorldSpaceCameraPos.xyz - worldSpacePivot;
// camera up vector
// used equally a somewhat capricious starting up orientation
float3 up = UNITY_MATRIX_I_V._m01_m11_m2;
// forward vector is the normalized beginning
// this it the direction from the pivot to the camera
float3 frontward = normalize(worldSpacePivotToCamera);
// cross product gets a vector perpendicular to the input vectors
float3 right = normalize(cross(forward, upwards));
// some other cross product ensures the upward is perpendicular to both
upward = cross(correct, forrad);
// construct the rotation matrix
float3x3 rotMat = float3x3(right, upward, forward);
// the above rotate matrix is transposed, significant the components are
// in the wrong society, but we can piece of work with that by swapping the
// order of the matrix and vector in the mul()
float3 worldPos = mul(5.vertex.xyz, rotMat) + worldSpacePivot;
// ray direction
float3 worldRayDir = worldPos - _WorldSpaceCameraPos.xyz;
o.rayDir = mul(unity_WorldToObject, float4(worldRayDir, 0.0));
// clip infinite position output
o.pos = UnityWorldToClipPos(worldPos);

            float3 worldPos = mul(float3(v.vertex.xy, 0.3), rotMat) + worldSpacePivot;          

Perfect Perspective Billboard Scaling

            // get the sine of the right triangle with the hypotenuse being the // sphere pivot altitude and the opposite using the sphere radius
float sinAngle = 0.five / length(viewOffset);
// catechumen to cosine
bladder cosAngle = sqrt(i.0 - sinAngle * sinAngle);
// convert to tangent
float tanAngle = sinAngle / cosAngle;
// those previous ii lines are the equivalent of this, but faster
// tanAngle = tan(asin(sinAngle));
// go the opposite face of the right triangle with the 90 degree
// angle at the sphere pin, multiplied by ii to go the quad size
float quadScale = tanAngle * length(viewOffset) * two.0;
// scale the quad by the calculated size
float3 worldPos = mul(float3(v.vertex.xy, 0.0) * quadScale, rotMat) + worldSpacePivot;

Bookkeeping for Object Scale

            // become the object scale
float3 calibration = float3(
length(unity_ObjectToWorld._m00_m10_m20),
length(unity_ObjectToWorld._m01_m11_m21),
length(unity_ObjectToWorld._m02_m12_m22)
);
float maxScale = max(abs(scale.x), max(abs(scale.y), abs(scale.z)));
// multiply the sphere radius past the max scale
bladder maxRadius = maxScale * 0.5;
// update our sine adding using the new radius
float sinAngle = maxRadius / length(viewOffset);
// do the rest of the scaling lawmaking

Ellipsoid Premises?

Frustum Culling

Shadow Casting

Orthographic Pain

            // forwards in view infinite is -z, so we want the negative vector
float3 worldSpaceViewForward = -UNITY_MATRIX_I_V._m02_m12_m22;
            float4x4 inverse(float4x4 k) {
bladder n11 = m[0][0], n12 = m[1][0], n13 = thou[ii][0], n14 = m[iii][0];
float n21 = g[0][1], n22 = m[1][1], n23 = one thousand[2][ane], n24 = m[3][1];
bladder n31 = g[0][two], n32 = chiliad[i][2], n33 = grand[2][ii], n34 = yard[3][two];
float n41 = m[0][3], n42 = m[1][3], n43 = one thousand[two][3], n44 = m[3][3];
float t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44; // ... hold upwardly, how many more lines are there of this?!

The Nearly View Plane

            // transform world space vertex position into view space
float4 viewSpacePos = mul(UNITY_MATRIX_V, float4(worldPos, 1.0));
// flatten the view space position to be on the camera plane
viewSpacePos.z = 0.0;
// transform back into world space
float4 worldRayOrigin = mul(UNITY_MATRIX_I_V, viewSpacePos);
// orthographic ray dir
float3 worldRayDir = worldSpaceViewForward;
// and to object infinite
o.rayDir = mul(unity_WorldToObject, float4(worldRayDir, 0.0));
o.rayOrigin = mul(unity_WorldToObject, worldRayOrigin);
            float3 worldSpaceViewPos =               UNITY_MATRIX_I_V._m03_m13_m23;
float3 worldSpaceViewForward = -UNITY_MATRIX_I_V._m02_m12_m2;
// originally the perspective ray dir
float3 worldCameraToPos = worldPos - worldSpaceViewPos;
// orthographic ray dir
float3 worldRayDir = worldSpaceViewForward * -dot(worldCameraToPos, worldSpaceViewForward);
// orthographic ray origin
float3 worldRayOrigin = worldPos - worldRayDir;
o.rayDir = mul(unity_WorldToObject, float4(worldRayDir, 0.0));
o.rayOrigin = mul(unity_WorldToObject, float4(worldRayOrigin, 1.0));

Light Facing Billboard

A Point of Perspective

            bool isOrtho = UNITY_MATRIX_P._m33 == one.0;            // billboard code
float3 forward = isOrtho ? -worldSpaceViewForward : normalize(worldSpacePivotToCamera);
// do the residue of the billboard lawmaking
// quad scaling code
float quadScale = maxScale;
if (!isOrtho)
{
// exercise that perfect scaling lawmaking
}
// ray direction and origin code
float3 worldRayOrigin = worldSpaceViewPos;
float3 worldRayDir = worldPos - worldSpaceRayOrigin;
if (isOrtho)
{
worldRayDir = worldSpaceViewForward * -dot(worldRayDir, worldSpaceViewForward);
worldRayOrigin = worldPos - worldRayDir;
}
o.rayDir = mul(unity_WorldToObject, float4(worldRayDir, 0.0));
o.rayOrigin = mul(unity_WorldToObject, float4(worldRayOrigin, 1.0));
// don't worry, I'll show the whole vertex shader after

Shadow Bias

Yes, actually still simply a quad.
            Tags { "LightMode" = "ShadowCaster" }            ZWrite On ZTest LEqual            CGPROGRAM
#pragma vertex vert
#pragma fragment frag_shadow
#pragma multi_compile_shadowcaster // yes, I know the vertex function is missing fixed4 frag_shadow (v2f i,
out float outDepth : SV_Depth
) : SV_Target
{
// ray origin
float3 rayOrigin = i.rayOrigin;
// normalize ray vector
float3 rayDir = normalize(i.rayDir);
// ray sphere intersection
float rayHit = sphIntersect(rayOrigin, rayDir, float4(0,0,0,0.5));
// above function returns -1 if there's no intersection
clip(rayHit);
// calculate object space position
float3 objectSpacePos = rayDir * rayHit + rayOrigin;
// output modified depth
// yes, we pass in objectSpacePos as both arguments
// second one is for the object space normal, which in this instance
// is the normalized position, just the function transforms it
// into world space and normalizes information technology so we don't accept to
float4 clipPos = UnityClipSpaceShadowCasterPos(objectSpacePos, objectSpacePos);
clipPos = UnityApplyLinearShadowBias(clipPos);
outDepth = clipPos.z / clipPos.west;
return 0;
}
ENDCG
            #if !defined(UNITY_REVERSED_Z) // basically only OpenGL
outDepth = outDepth * 0.five + 0.5;

0 Response to "how to draw sphere in 3d"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel