为了给Optix添加凹凸纹理,我们需要利用一张高度图来计算法向的方向。而高度图是一张单通道的图片,所以我暂时将高度图存储在BMP图片的alpha通道中。然后在切线空间中利用高度图计算出干扰法线,利用发现来模拟凹凸纹理。
纹理坐标和几何坐标结合在一起可以计算出切线空间的转换。计算代码如下:
static __device__ void make_tangent_space(float3 p0,float3 p1,float3 p2,float2 t0,float2 t1,float2 t2)
{
float3 P10=p1-p0;
float3 P20=p2-p0;
float2 C10=t1-t0; //(U10,V10)
float2 C20=t2-t0; //(U20,V20)
float U10=C10.x,V10=C10.y;
float U20=C20.x,V20=C20.y;
float factor=1.0/(U10*V20-U20*V10);
float3 tmp_tangent,tmp_binormal;
tmp_tangent.x = factor*(V20*P10.x+(-V10)*P20.x);
tmp_tangent.y = factor*(V20*P10.y+(-V10)*P20.y);
tmp_tangent.z = factor*(V20*P10.z+(-V10)*P20.z);
tmp_binormal.x = factor*((-U20)*P10.x+U10*P20.x);
tmp_binormal.y = factor*((-U20)*P10.y+U10*P20.y);
tmp_binormal.z = factor*((-U20)*P10.z+U10*P20.z);
shading_tangent = tmp_tangent;
shading_binormal=tmp_binormal;
}
ffnormal = ffnormal - x_grad * T - y_grad * B; //凹纹理
ffnormal = ffnormal + x_grad * T + y_grad * B; //凸纹理
float h0 = tex2D( diffuse_map, uv.x-1.0/width, uv.y ).w;
float h1 = tex2D( diffuse_map, uv.x+1.0/width, uv.y ).w;
float h2 = tex2D( diffuse_map, uv.x, uv.y-1/height ).w;
float h3 = tex2D( diffuse_map, uv.x, uv.y+1/height ).w;
float depth = 5; /*纹理的深度*/
float x_grad= (h0-h1)*depth;
float y_grad= (h2-h3)*depth;