Shaders in Unity — Intro | by Deshan Kalupahana | Medium
Shaders in Unity — Flat Color | by Deshan Kalupahana | Medium
Shaders in Unity — Lambert and Ambient | by Deshan Kalupahana | Medium
Just another Kyoung Shin Park's Lectures Sites site
(Image fromhttps://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_reflection_model)
Ambient/Diffuse/Specular (Image from https://en.wikipedia.org/wiki/Phong_reflection_model)
lecture13
lecture12
public static Quaternion LookRotation(Vector3 forward, [DefaultValue(“Vector3.up”)] Vector3 upwards)
{
return Quaternion.INTERNAL_CALL_LookRotation(ref forward, ref upwards);
}
[ExcludeFromDocs]
public static Quaternion LookRotation(Vector3 forward)
{
Vector3 up = Vector3.up;
return Quaternion.INTERNAL_CALL_LookRotation(ref forward, ref up);
}
// from http://answers.unity3d.com/questions/467614/what-is-the-source-code-of-quaternionlookrotation.html
private static Quaternion INTERNAL_CALL_LookRotation(ref Vector3 forward, ref Vector3 up)
{
forward = Vector3.Normalize(forward);
Vector3 right = Vector3.Normalize(Vector3.Cross(up, forward));
up = Vector3.Cross(forward, right);
var m00 = right.x;
var m01 = right.y;
var m02 = right.z;
var m10 = up.x;
var m11 = up.y;
var m12 = up.z;
var m20 = forward.x;
var m21 = forward.y;
var m22 = forward.z;
float num8 = (m00 + m11) + m22;
var quaternion = new Quaternion();
if (num8 > 0f)
{
var num = (float)Math.Sqrt(num8 + 1f);
quaternion.w = num * 0.5f;
num = 0.5f / num;
quaternion.x = (m12 – m21) * num;
quaternion.y = (m20 – m02) * num;
quaternion.z = (m01 – m10) * num;
return quaternion;
}
if ((m00 >= m11) && (m00 >= m22))
{
var num7 = (float)Math.Sqrt(((1f + m00) – m11) – m22);
var num4 = 0.5f / num7;
quaternion.x = 0.5f * num7;
quaternion.y = (m01 + m10) * num4;
quaternion.z = (m02 + m20) * num4;
quaternion.w = (m12 – m21) * num4;
return quaternion;
}
if (m11 > m22)
{
var num6 = (float)Math.Sqrt(((1f + m11) – m00) – m22);
var num3 = 0.5f / num6;
quaternion.x = (m10 + m01) * num3;
quaternion.y = 0.5f * num6;
quaternion.z = (m21 + m12) * num3;
quaternion.w = (m20 – m02) * num3;
return quaternion;
}
var num5 = (float)Math.Sqrt(((1f + m22) – m00) – m11);
var num2 = 0.5f / num5;
quaternion.x = (m20 + m02) * num2;
quaternion.y = (m21 + m12) * num2;
quaternion.z = 0.5f * num5;
quaternion.w = (m01 – m10) * num2;
return quaternion;
}
Matrix4x4.LookAt(Vector3 from, Vector4 to, Vector3 up) creates a “look at” matrix.
which is equal to Matrix4x4.TRS(from, Quaternion.LookRotation((to-from).normalized, up.normalized), Vector3.one)
Note that: glm::lookat != Matrix4x4.LookAt
template <typename T, precision P>
GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAt(tvec3<T, P> const & eye, tvec3<T, P> const & center, tvec3<T, P> const & up)
{
# if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED
return lookAtLH(eye, center, up);
# else
return lookAtRH(eye, center, up);
# endif
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAtRH
(
tvec3<T, P> const & eye,
tvec3<T, P> const & center,
tvec3<T, P> const & up
)
{
tvec3<T, P> const f(normalize(center – eye));
tvec3<T, P> const s(normalize(cross(f, up)));
tvec3<T, P> const u(cross(s, f));
tmat4x4<T, P> Result(1);
Result[0][0] = s.x;
Result[1][0] = s.y;
Result[2][0] = s.z;
Result[0][1] = u.x;
Result[1][1] = u.y;
Result[2][1] = u.z;
Result[0][2] =-f.x;
Result[1][2] =-f.y;
Result[2][2] =-f.z;
Result[3][0] =-dot(s, eye);
Result[3][1] =-dot(u, eye);
Result[3][2] = dot(f, eye);
return Result;
}
template <typename T, precision P>
GLM_FUNC_QUALIFIER tmat4x4<T, P> lookAtLH
(
tvec3<T, P> const & eye,
tvec3<T, P> const & center,
tvec3<T, P> const & up
)
{
tvec3<T, P> const f(normalize(center – eye));
tvec3<T, P> const s(normalize(cross(up, f)));
tvec3<T, P> const u(cross(f, s));
tmat4x4<T, P> Result(1);
Result[0][0] = s.x;
Result[1][0] = s.y;
Result[2][0] = s.z;
Result[0][1] = u.x;
Result[1][1] = u.y;
Result[2][1] = u.z;
Result[0][2] = f.x;
Result[1][2] = f.y;
Result[2][2] = f.z;
Result[3][0] = -dot(s, eye);
Result[3][1] = -dot(u, eye);
Result[3][2] = -dot(f, eye);
return Result;
}
Z-fighting, also called stitching, is a phenomenon in 3D rendering that occurs when two or more primitives have similar values in the z-buffer. This problem is usually caused by limited sub-pixel precision and floating point and fixed point round-off errors.
The more z-buffer precision one uses, the less likely it is that z-fighting will be encountered. But for coplanar polygons, the problem is inevitable unless corrective action is taken.
As the distance between near and far clip planes increases, and in particular the near plane is selected near the eye, the greater the likelihood exists that z-fighting between primitives will occur.
Z-fighting can be reduced through the use of a higher resolution depth buffer, by z-buffering in some scenarios, or by simply moving the polygons further apart.
Z-fighting that is caused by insufficient precision in the depth buffer can be resolved by simply reducing the visible distance in the world. This reduces the distance between the near and far planes and solves the precision issue.
Another technique that is utilized to reduce or completely eliminate Z-fighting is switching to a logarithmic Z-buffer, reversing Z. This technique is seen in the game Grand Theft Auto V. Due to the way they are encoded, floating-point numbers have much more precision when closer to 0. Here, reversing Z leads to more precision when storing the depth of very distant objects, hence greatly reducing Z-fighting.
https://en.wikipedia.org/wiki/Z-fighting
There is very high precision at the near plane, but very little precision at the far plane. If the range [-n, -f] is getting larger, it causes a depth precision problem (z-fighting); a small change of ze around the far plane does not affect on zn value. The distance between n and f should be short as possible to minimize the depth buffer precision problem.
http://www.songho.ca/opengl/gl_projectionmatrix.html
reversed-Z
Orthographic Projection
template <typename T> GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> ortho ( T left, T right, T bottom, T top, T zNear, T zFar ) { tmat4x4<T, defaultp> Result(1); Result[0][0] = static_cast<T>(2) / (right - left); Result[1][1] = static_cast<T>(2) / (top - bottom); Result[2][2] = - static_cast<T>(2) / (zFar - zNear); Result[3][0] = - (right + left) / (right - left); Result[3][1] = - (top + bottom) / (top - bottom); Result[3][2] = - (zFar + zNear) / (zFar - zNear); return Result; }
Perspective Projection
template <typename T> GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> frustum ( T left, T right, T bottom, T top, T nearVal, T farVal ) { tmat4x4<T, defaultp> Result(0); Result[0][0] = (static_cast<T>(2) * nearVal) / (right - left); Result[1][1] = (static_cast<T>(2) * nearVal) / (top - bottom); Result[2][0] = (right + left) / (right - left); Result[2][1] = (top + bottom) / (top - bottom); Result[2][2] = -(farVal + nearVal) / (farVal - nearVal); Result[2][3] = static_cast<T>(-1); Result[3][2] = -(static_cast<T>(2) * farVal * nearVal) / (farVal - nearVal); return Result; }
http://www.songho.ca/opengl/gl_projectionmatrix.html
mat4 projectionMatrix = glm::perspective (float fovy, float aspect, float near, float far) fovy radian
top = tan(fovy/2) * near
right = top * aspect
projectionMatrix = glm::frustum(-right, right, -top, top, near, far)