使用 directx9 或 DX11 实现区域光
Area Light Implementation with directx9 or DX11
我想使用 Directx 9 实现 AreaLight 请帮助我如何开始。我研究了两个三个 link 但能够在 RenderMonkey 或 Direct With Sample
中实现
球形区域光 HLSL
float specTrowbridgeReitz(float HoN,float a,float aP)
{
float a2 = a*a;
float ap2 = aP*aP;
return ( a2 * ap2 ) / pow( HoN * HoN * ( a2 - 1.0 ) + 1.0, 2.0 );
}
float visSchlickSmithMod( float NoL, float NoV, float r )
{
float k = pow( r * 0.5 + 0.5, 2.0 ) * 0.5;
float l = NoL * ( 1.0 - k ) + k;
float v = NoV * ( 1.0 - k ) + k;
return 1.0 / ( 4.0 * l * v );
}
float fresSchlickSmith( float HoV, float f0 )
{
return f0 + ( 1.0 - f0 ) * pow( 1.0 - HoV, 5.0 );
}
float sphereLight(float3 pos,float3 N,float3 V,float3 r,float f0,float
roughness,float NoV,out float NoL)
{
float3 L = lightPositions - pos;
float3 centerToRay = dot(L,r)*r-L;
float3 closestPoint = L + centerToRay * clamp( fLightRadius / length(
centerToRay ), 0.0, 1.0 );
float3 l = normalize(closestPoint);
float3 h = normalize(V+l);
NoL = clamp(dot(N,l),0.0,1.0);
float HoN = clamp(dot(h,N),0.0,1.0);
float HoV = dot(h,V);
float distL = length(L);
float alpha = roughness * roughness;
float alphaPrime = clamp(fLightRadius/(distL*2.0)+alpha,0.0,1.0);
float specD = specTrowbridgeReitz( HoN, alpha, alphaPrime );
float specF = fresSchlickSmith( HoV, f0 );
float specV = visSchlickSmithMod( NoL, NoV, roughness );
return specD * specF * specV*NoL;
}
float3 areaLights(float3 pos,float3 nor,float3 V)
{
float f0 = FO;
float NoV = clamp(dot(nor,V),0.0,1.0);
float3 r = reflect(-V,nor);
float NdotLSphere;
float specSph = sphereLight(pos,nor,V,r,f0,roughness,NoV,NdotLSphere);
float3 color = 0.3183*(NdotLSphere*lightcolor)+
(specSph*lightcolor)+albedo;
return pow(color,1.0/2.2);
}
float4 ps_main( PS_INPUT Input ) : COLOR0
{
float3 N = normalize(Input.Normal);
float3 viewDir = normalize(campos.xyz -
float3(Input.WSPosition.xyz));
float3 color = areaLights(Input.WSPosition,N,viewDir);
return float4(color,0.0);
}
我想使用 Directx 9 实现 AreaLight 请帮助我如何开始。我研究了两个三个 link 但能够在 RenderMonkey 或 Direct With Sample
中实现球形区域光 HLSL
float specTrowbridgeReitz(float HoN,float a,float aP)
{
float a2 = a*a;
float ap2 = aP*aP;
return ( a2 * ap2 ) / pow( HoN * HoN * ( a2 - 1.0 ) + 1.0, 2.0 );
}
float visSchlickSmithMod( float NoL, float NoV, float r )
{
float k = pow( r * 0.5 + 0.5, 2.0 ) * 0.5;
float l = NoL * ( 1.0 - k ) + k;
float v = NoV * ( 1.0 - k ) + k;
return 1.0 / ( 4.0 * l * v );
}
float fresSchlickSmith( float HoV, float f0 )
{
return f0 + ( 1.0 - f0 ) * pow( 1.0 - HoV, 5.0 );
}
float sphereLight(float3 pos,float3 N,float3 V,float3 r,float f0,float
roughness,float NoV,out float NoL)
{
float3 L = lightPositions - pos;
float3 centerToRay = dot(L,r)*r-L;
float3 closestPoint = L + centerToRay * clamp( fLightRadius / length(
centerToRay ), 0.0, 1.0 );
float3 l = normalize(closestPoint);
float3 h = normalize(V+l);
NoL = clamp(dot(N,l),0.0,1.0);
float HoN = clamp(dot(h,N),0.0,1.0);
float HoV = dot(h,V);
float distL = length(L);
float alpha = roughness * roughness;
float alphaPrime = clamp(fLightRadius/(distL*2.0)+alpha,0.0,1.0);
float specD = specTrowbridgeReitz( HoN, alpha, alphaPrime );
float specF = fresSchlickSmith( HoV, f0 );
float specV = visSchlickSmithMod( NoL, NoV, roughness );
return specD * specF * specV*NoL;
}
float3 areaLights(float3 pos,float3 nor,float3 V)
{
float f0 = FO;
float NoV = clamp(dot(nor,V),0.0,1.0);
float3 r = reflect(-V,nor);
float NdotLSphere;
float specSph = sphereLight(pos,nor,V,r,f0,roughness,NoV,NdotLSphere);
float3 color = 0.3183*(NdotLSphere*lightcolor)+
(specSph*lightcolor)+albedo;
return pow(color,1.0/2.2);
}
float4 ps_main( PS_INPUT Input ) : COLOR0
{
float3 N = normalize(Input.Normal);
float3 viewDir = normalize(campos.xyz -
float3(Input.WSPosition.xyz));
float3 color = areaLights(Input.WSPosition,N,viewDir);
return float4(color,0.0);
}