Danbias/OysterGraphics/Shader/HLSL/LightMaterialMethods.hlsl

151 lines
5.2 KiB
HLSL

// Personal notes and trail of thought //////////////////////////////
/*
Light is flux ( latin fluxus ; flow )
(F1) Flux density : amount of flow through a cross section (A)
(L) Luminosity: property of light, amount of light output per time. Equivalent with the Watt unit.
(A) Area as a function of range(r).
A[r] = 4*PI*r^2
F1 = L / A[r] = L / ( 4*PI*r^2 )
_Attenuation_
Attenuation is the gradual loss in intensity of any kind of flux through a medium. ~ Wikipedia
It is also dependant of BOTH medium material and type of Flux. Attenuation( soft Tissue, Light ) != Attenuation( soft Tissue, Xray ).
Hm'Yeah .. lets not use that. And SHAME to those who use that word carelessly in computer graphics!!!
_Attenuation_coefficient_
The linear intensity loss of a narrow beam through a medium.
Hm .. This sounds CG delicious :)
F2 = L / ( AttCoeff * r )
_Total:_
F = F1 + F2 = L / ( 4*PI*r^2 ) + L / ( AttCoeff * r ) = L / ( AttCoeff*r + 4*PI*r^2 )
May vary between light spreadTypes -------^^^^
L = ( Red Luminosity, Green Luminosity, Blue Luminosity, Spread )
F = ( Red Density, Green Density, Blue Density ) = L.rgb / (AttCoeff*r + L.s^2)
AttCoeff : property of Enviroment
Ambience Light : property of Enviroment
*/
#ifndef LIGHTMATERIALMETHODS_HLSL
#define LIGHTMATERIALMETHODS_HLSL
#include "CollisionMethods.hlsl"
#define PI 3.1415926535897932384626433832795f
#define POINTLIGHT_SPREADCOEFF 12.566370614359172953850573533118f
struct PointLight
{
Sphere pos;
float3 color;
float intensity;
};
void accumulateLight( inout float3 diffusePixel, inout float3 specularPixel, uniform in PointLight lightV, uniform in float exposure, uniform in float specularGloss, uniform in float3 pixelPosV, uniform in float3 normalV )
{
float3 toLightVecV = lightV.pos.center - pixelPosV;
float range = length( toLightVecV );
if( !(range <= lightV.pos.radius ) )
{
return;
}
toLightVecV /= range;
float3 illum = lightV.color;
illum *= (exposure * lightV.intensity) / ( range + (POINTLIGHT_SPREADCOEFF * pow(range, 2.0f)) ); // light density on all rgb channels
// calculating and adding the DiffuseCoefficient
float coeff = max( dot(toLightVecV, normalV), 0.0f );
diffusePixel += illum * coeff;
if( coeff > 0.0f )
{ // calculating and adding the SpecularCoefficient
coeff = max( dot( reflect(-toLightVecV, normalV), normalize(-pixelPosV) ), 0.0f );
specularPixel += illum * pow( coeff, specularGloss );
}
}
// ------------------ old below
/*
struct Medium
{
float3 ambienceLuminosity;
float attenuationCoeff;
};
struct Light
{
matrix worldToLightVolume;
float3 luminosity;
float spreadCoeff;
float4 orientation;
};
// returns light density per rgb channel
float3 calcLightDensity( uniform float rangeW, uniform Light light, uniform Medium enviroment )
{ return light.luminosity / ( (enviroment.attenuationCoeff * rangeW) + (light.spreadCoeff * pow(rangeW, 2.0f)) ); }
// returns light density per rgb channel
float3 calcLightDensity( uniform float rangeW, uniform Light light )
{ return light.luminosity / ( rangeW + (light.spreadCoeff * pow(rangeW, 2.0f)) ); }
float calcDiffuseCoeff( uniform float3 normalW, uniform float3 toLightVecW )
{ return max( dot( toLightVecW, normalW ), 0.0f ); }
float calcSpecularCoeff( uniform float3 normalW, uniform float3 toLightVecW, uniform float3 toObserverVecW )
{ return max( dot( reflect( -toLightVecW, normalW ), toObserverVecW ), 0.0f ); }
/////////////////////////////////////////////////////////////////////
// SHADOW SAMPLING
/////////////////////////////////////////////////////////////////////
/*SamplerComparisonState shadowSampling
{
Filter = COMPARISON_MIN_MAG_MIP_POINT;
ComparisonFunc = LESS_EQUAL;
AddressU = BORDER;
AddressV = BORDER;
AddressW = BORDER;
BorderColor = float4( 0.0f, 0.0f, 0.0f, 0.0f );
};/**/
/*
SamplerState shadowSampling
{
Filter = MIN_MAG_MIP_POINT;
AddressU = BORDER;
AddressV = BORDER;
AddressW = BORDER;
BorderColor = float4( 0.0f, 0.0f, 0.0f, 0.0f );
};/**/
/*
void sampleShadowPCFx4( uniform float3 posW, uniform Light light, uniform Texture2D shadowMap, uniform float2 shadowMapResolution, out float lightExposure, out float range )
{
float4 value = mul( light.worldToLightVolume, float4(posW, 1.0f) );
value /= value.w;
float2 shadowUV = 0.5f*( float2(value.x, -value.y) + 1.0f );
float2 shadowUVDelta = 1.0f / shadowMapResolution;
range = value.z - 0.00390625f;
//lightExposure = shadowMap.SampleCmpLevelZero( shadowSampling, shadowUV, range ).r;
value.x = (float)shadowMap.Sample(shadowSampling, shadowUV ).r;
value.y = (float)shadowMap.Sample(shadowSampling, shadowUV + float2(shadowUVDelta.x, 0.0f) );
value.z = (float)shadowMap.Sample(shadowSampling, shadowUV + float2(0.0f, shadowUVDelta.y) );
value.w = (float)shadowMap.Sample(shadowSampling, shadowUV + shadowUVDelta );
value.x = range > value.x ? 0.0f : 1.0f; // 1.0f if lightRange is not lesser than range. Else 0.0f
value.y = range > value.y ? 0.0f : 1.0f;
value.z = range > value.z ? 0.0f : 1.0f;
value.w = range > value.w ? 0.0f : 1.0f;
range += 0.00390625f;
shadowUV = frac( shadowUV * shadowMapResolution );
lightExposure = lerp( lerp( value.x, value.y, shadowUV.x ), lerp( value.z, value.w, shadowUV.x ), shadowUV.y );
}
*/
#endif