在二维上我们画一个圆实际上就是定义一个pos 然后 周围的uv判断是否在圆内
三维上我们画一个球,实际上就是三维的坐标到某个pos来判断是否在球内
看一下作者的做法
float3 rayOrigin = viewDir - worldPos;
float3 offset = viewDir * 1;
float result = 0.0f;
for(int i = 0; i < 256; i++)
{
float dist = length(rayOrigin - sphereCenter) - sphereRadius;
if (dist < 0.01f)
{
return float3(1.0f, 0.0f, 0.0f);
}
rayOrigin += offset;
}
return float3(0.0f, 0.0f, 0.0f);
我们需要知道的是,这个球实际上还是我们在物体的表面上形成的视觉欺骗的效果,我们设置为平面并且设置为rayOrigin的颜色
float3 rayOrigin = viewDir - worldPos;
float3 offset = viewDir * 1;
float result = 0.0f;
for(int i = 0; i < 256; i++)
{
float dist = length(rayOrigin - sphereCenter) - sphereRadius;
if (dist < 0.01f)
{
return rayOrigin;
}
rayOrigin += offset;
}
return float3(0.0f, 0.0f, 0.0f);
其实我还是不是很理解这个球怎么算的,我的感觉就是作者的做法是为了让它立体
problem
因为这里是相对于worldpossition来偏移的,当我们在世界中使用的时候无法显示
获取obj的中心坐标然后减去像素的世界坐标让它变成相对obj的局部坐标
然后就可以得到世界空间的效果
通过增加输出转换为不透明遮罩得到一个比较不错的三维球体
float3 rayOrigin = viewDir - worldPos;
float3 offset = viewDir * 1;
float result = 0.0f;
for(int i = 0; i < 256; i++)
{
float dist = length(rayOrigin - sphereCenter) - sphereRadius;
if (dist < 0.01f)
{
mask = 1.0;
return rayOrigin;
}
rayOrigin += offset;
}
mask = 0.0;
return float3(0.0f, 0.0f, 0.0f);
加入diffuse light
float3 rayOrigin = worldPos - viewDir;
float3 offset = viewDir * -1;
float result = 0.0f;
for(int i = 0; i < 256; i++)
{
float dist = length(rayOrigin - sphereCenter) - sphereRadius;
if (dist < 0.01f)
{
mask = 1.0;
float3 normal = normalize(rayOrigin - sphereCenter);
float3 diffuse = max(dot(normal, lightPos), 0.0f);
return float3(1.0f, 0.0f, 0.0f) * diffuse;
}
rayOrigin += offset;
}
mask = 0.0;
return float3(0.0f, 0.0f, 0.0f);
记得把原本的颜色去掉
Specular
float3 rayOrigin = worldPos - viewDir;
float3 offset = viewDir * -1;
float result = 0.0f;
for(int i = 0; i < 256; i++)
{
float dist = length(rayOrigin - sphereCenter) - sphereRadius;
if (dist < 0.01f)
{
mask = 1.0;
float3 normal = normalize(rayOrigin - sphereCenter);
float diffuse = max(dot(normal, lightPos), 0.0f);
float3 h = normalize((viewDir + lightPos));
float spec = pow(max(dot(normal, h), 0.0f), specRate);
return float3(1.0f, 0.0f, 0.0f) * diffuse + float3(1.0f, 1.0f, 1.0f) * spec;
}
rayOrigin += offset;
}
mask = 0.0;
return float3(0.0f, 0.0f, 0.0f);