您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
70 行
2.3 KiB
70 行
2.3 KiB
#ifndef UNITY_REFRACTION_INCLUDED
|
|
#define UNITY_REFRACTION_INCLUDED
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Util refraction
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct RefractionModelResult
|
|
{
|
|
float distance; // length of the transmission during refraction through the shape
|
|
float3 positionWS; // out ray position
|
|
float3 rayWS; // out ray direction
|
|
};
|
|
|
|
RefractionModelResult RefractionModelSphere(float3 V, float3 positionWS, float3 normalWS, float ior, float thickness)
|
|
{
|
|
// Sphere shape model:
|
|
// We approximate locally the shape of the object as sphere, that is tangent to the shape.
|
|
// The sphere has a diameter of {thickness}
|
|
// The center of the sphere is at {positionWS} - {normalWS} * {thickness}
|
|
//
|
|
// So the light is refracted twice: in and out of the tangent sphere
|
|
|
|
// First refraction (tangent sphere in)
|
|
// Refracted ray
|
|
float3 R1 = refract(-V, normalWS, 1.0 / ior);
|
|
// Center of the tangent sphere
|
|
float3 C = positionWS - normalWS * thickness * 0.5;
|
|
|
|
// Second refraction (tangent sphere out)
|
|
float NoR1 = dot(normalWS, R1);
|
|
// Optical depth within the sphere
|
|
float distance = -NoR1 * thickness;
|
|
// Out hit point in the tangent sphere
|
|
float3 P1 = positionWS + R1 * distance;
|
|
// Out normal
|
|
float3 N1 = normalize(C - P1);
|
|
// Out refracted ray
|
|
float3 R2 = refract(R1, N1, ior);
|
|
float N1oR2 = dot(N1, R2);
|
|
float VoR1 = dot(V, R1);
|
|
|
|
RefractionModelResult result;
|
|
result.distance = distance;
|
|
result.positionWS = P1;
|
|
result.rayWS = R2;
|
|
|
|
return result;
|
|
}
|
|
|
|
RefractionModelResult RefractionModelPlane(float3 V, float3 positionWS, float3 normalWS, float ior, float thickness)
|
|
{
|
|
// Plane shape model:
|
|
// We approximate locally the shape of the object as a plane with normal {normalWS} at {positionWS}
|
|
// with a thickness {thickness}
|
|
|
|
// Refracted ray
|
|
float3 R = refract(-V, normalWS, 1.0 / ior);
|
|
|
|
// Optical depth within the thin plane
|
|
float distance = thickness / dot(R, -normalWS);
|
|
|
|
RefractionModelResult result;
|
|
result.distance = distance;
|
|
result.positionWS = positionWS + R * distance;
|
|
result.rayWS = -V;
|
|
|
|
return result;
|
|
}
|
|
#endif
|