Files
clientdata/vertex_program/include/functions.inc
T
2018-04-24 13:27:52 -04:00

473 lines
17 KiB
C++
Executable File

// ======================================================================
// functions.inc
// HLSL vertex shader functions
// ======================================================================
#include "../../shared_program/functions.inc"
// ======================================================================
float4 transform3d(float4 vertexPosition_o)
{
return mul(vertexPosition_o, objectWorldCameraProjectionMatrix);
}
// ----------------------------------------------------------------------
float4 transform2d(float2 vertexPosition_s)
{
float4 result;
result.x = (vertexPosition_s.x * viewportData.x) + viewportData.z;
result.y = (vertexPosition_s.y * viewportData.y) + viewportData.w;
result.z = 0.5;
result.w = 1.0;
return result;
}
// ----------------------------------------------------------------------
float3 rotate_o2w(float3 vector_o)
{
return mul(vector_o, (float3x3)objectWorldMatrix);
}
// ----------------------------------------------------------------------
float3 rotateNormalize_o2w(float3 vector_o)
{
return normalize(rotate_o2w(vector_o));
}
// ----------------------------------------------------------------------
float3 rotateTranslate_o2w(float3 vector_o)
{
return mul(vector_o, objectWorldMatrix);
}
// ----------------------------------------------------------------------
float3 calculateHalfAngle_o(float3 position_o)
{
return normalize(lightData.dot3[0].direction_o + normalize(lightData.dot3[0].cameraPosition_o - position_o));
}
// ----------------------------------------------------------------------
//float3 calculateReflectionVector_w(float3 position_o, float3 normal_o)
//{
// float3 fromViewer_w = normalize(rotateTranslate_o2w(position_o) - cameraPosition);
// float3 normal_w = rotateTranslateNormalize_o2w(normal_o);
// return reflect(fromViewer_w, normal_w);
//}
// ----------------------------------------------------------------------
float calculateFog(float4 vertexPosition_o)
{
float4 position_w = mul(vertexPosition_o, objectWorldMatrix);
float3 viewer_w = cameraPosition_w - position_w;
float viewerDistanceSquared = lengthSquared(viewer_w);
return 1.0 / exp(viewerDistanceSquared * fog.w);
}
// ----------------------------------------------------------------------
float3x3 calculateTextureToWorldTransform(float3 vertexNormal_o, float4 tcsDOT3)
{
// build the transformation matrix
float3x3 m;
m[0] = rotate_o2w((float3)tcsDOT3);
m[2] = normalize(rotate_o2w(vertexNormal_o));
m[1] = cross(m[2], m[0]) * tcsDOT3.w;
return m;
}
// ----------------------------------------------------------------------
float3x3 calculateTextureToObjectTransform(float3 vertexNormal_o, float4 tcsDOT3)
{
// build the transformation matrix
float3x3 m;
m[0] = (float3)tcsDOT3;
m[2] = vertexNormal_o;
m[1] = cross(m[2], m[0]) * tcsDOT3.w;
return m;
}
// ----------------------------------------------------------------------
float3x3 calculateObjectToTextureTransform(float3 vertexNormal_o, float4 tcsDOT3)
{
return transpose(calculateTextureToObjectTransform(vertexNormal_o,tcsDOT3));
}
// ----------------------------------------------------------------------
float3 calculateDot3LightDirection_t(float3 vertexNormal_o, float4 tcsDOT3)
{
// transform the light direction into texture space
return mul(lightData.dot3[0].direction_o, calculateObjectToTextureTransform(vertexNormal_o, tcsDOT3));
}
// ----------------------------------------------------------------------
// deprecated
float3 transformDot3LightDirection(float3 vertexNormal_o, float4 tcsDOT3)
{
return calculateDot3LightDirection_t(vertexNormal_o, tcsDOT3);
}
// ----------------------------------------------------------------------
float3 computeHalfAngle(float3 vertexPosition_o)
{
// (H = L + V / |L + V|)
return normalize(normalize(lightData.dot3[0].cameraPosition_o - vertexPosition_o) + lightData.dot3[0].direction_o);
}
// ----------------------------------------------------------------------
float3 calculateHalfAngle_t(float3 vertexPosition_o, float3 vertexNormal_o, float4 tcsDOT3)
{
return mul(computeHalfAngle(vertexPosition_o), calculateObjectToTextureTransform(vertexNormal_o, tcsDOT3));
}
// ----------------------------------------------------------------------
// deprecated
float3 transformHalfAngle(float3 vertexPosition_o, float3 vertexNormal_o, float4 tcsDOT3)
{
return calculateHalfAngle_t(vertexPosition_o, vertexNormal_o, tcsDOT3);
}
// ----------------------------------------------------------------------
float3 transformTerrainDot3(float3 input, float3 vertexNormal_o)
{
float3 j = cross(vertexNormal_o, float3(1.0f, 0.0f, 0.0f));
float3 i = cross(j, vertexNormal_o);
float3x3 ot = float3x3(i, j, vertexNormal_o);
float3 result = mul(ot, input);
return result;
}
// ----------------------------------------------------------------------
float3 transformTerrainDot3LightDirection(float3 vertexNormal_o)
{
return normalize(transformTerrainDot3(lightData.dot3[0].direction_o, vertexNormal_o));
}
// ----------------------------------------------------------------------
float3 calculateViewerDirection_o(float3 vertexPosition_o)
{
return normalize(lightData.dot3[0].cameraPosition_o - vertexPosition_o);
}
// ----------------------------------------------------------------------
float3 calculateViewerDirection_w(float3 vertexPosition_o)
{
return normalize(cameraPosition_w - rotateTranslate_o2w(vertexPosition_o));
}
// ----------------------------------------------------------------------
float4 calculateDiffuseParallelLight(ParallelLight light, float3 vertexNormal_o)
{
float3 normal_w = normalize(mul(vertexNormal_o, (float3x3)objectWorldMatrix));
return max(dot(normal_w, light.direction_w), 0.0) * light.diffuseColor;
}
float4 calculateDiffuseParallelLightWorld(ParallelLight light, float3 normal_w)
{
return max(dot(normal_w, light.direction_w), 0.0) * light.diffuseColor;
}
// ----------------------------------------------------------------------
float4 calculateDiffuseParallelHemisphericLight(ParallelLight light, float3 normal_w, HemisphericLightData extendedLight)
{
float dotProduct = dot(normal_w, light.direction_w);
float3 color = extendedLight.tangentColor;
float intensity = max(0.0, dotProduct);
color += (-intensity * (extendedLight.tangentColorMinusDiffuseColor));
intensity = min(0.0, dotProduct);
color += (intensity * (extendedLight.tangentColorMinusBackColor));
float4 result;
result.rgb = color;
result.a = 0.f;
return result;
}
// ----------------------------------------------------------------------
DiffuseSpecular calculateDiffuseSpecularParallelLight(ParallelSpecularLight light, float4 vertexPosition_o, float3 vertexNormal_o)
{
float3 viewer_w = normalize(cameraPosition_w - mul(vertexPosition_o, objectWorldMatrix));
float3 vertexNormal_w = normalize(mul(vertexNormal_o, (float3x3)objectWorldMatrix));
float3 halfAngle = normalize(light.direction_w + viewer_w);
float nDotL = dot(vertexNormal_w, light.direction_w);
float nDotH = dot(vertexNormal_w, halfAngle);
float4 lighting = lit(nDotL, nDotH, material.specularPower.x);
DiffuseSpecular diffuseSpecular;
diffuseSpecular.diffuse = lighting.y * light.diffuseColor;
diffuseSpecular.diffuse.a = 0.f;
diffuseSpecular.specular = lighting.z * light.specularColor;
return diffuseSpecular;
}
// ----------------------------------------------------------------------
DiffuseSpecular calculateDiffuseSpecularParallelHemisphericLight(ParallelSpecularLight light, float3 vertexPosition_w, float3 vertexNormal_w, HemisphericLightData extendedLight)
{
float3 viewer_w = normalize(cameraPosition_w - vertexPosition_w);
float3 halfAngle = normalize(light.direction_w + viewer_w);
float nDotL = dot(vertexNormal_w, light.direction_w);
float nDotH = dot(vertexNormal_w, halfAngle);
float4 lighting = lit(nDotL, nDotH, material.specularPower.x);
DiffuseSpecular diffuseSpecular;
diffuseSpecular.diffuse = extendedLight.tangentColor;
diffuseSpecular.diffuse += (-lighting.y * (extendedLight.tangentColorMinusDiffuseColor));
float intensity = min(nDotL, 0.0);
diffuseSpecular.diffuse += (intensity * (extendedLight.tangentColorMinusBackColor));
diffuseSpecular.diffuse.a = 0.f;
diffuseSpecular.specular = lighting.z * light.specularColor;
return diffuseSpecular;
}
// ----------------------------------------------------------------------
float4 calculateDiffusePointLight(PointLight light, float3 vertexPosition_w, float3 normal_w)
{
// Get light direction
float3 lightDirection = light.position_w - vertexPosition_w;
// Get light distance squared.
float lightDistanceSquared = lengthSquared(lightDirection);
// Get 1/lightDistance
float oneOverLightDistance = rsqrt(lightDistanceSquared);
// Normalize light direction
lightDirection *= oneOverLightDistance;
// compute distance attenuation
float4 attenuationFactors;
attenuationFactors.x = 1.0;
attenuationFactors.y = lightDistanceSquared * oneOverLightDistance;
attenuationFactors.z = lightDistanceSquared;
attenuationFactors.w = oneOverLightDistance;
float distanceAttenuation = 1.0 / dot(light.attenuation, attenuationFactors);
return max(dot(normal_w, lightDirection), 0.0) * distanceAttenuation * light.diffuseColor;
}
// ----------------------------------------------------------------------
DiffuseSpecular calculateDiffuseSpecularPointLight(PointSpecularLight light, float4 vertexPosition_o, float3 vertexNormal_o)
{
float3 vertexPosition_w = mul(vertexPosition_o, objectWorldMatrix);
float3 normal_w = normalize(mul(vertexNormal_o, (float3x3)objectWorldMatrix));
float3 viewer_w = normalize(cameraPosition_w - vertexPosition_w);
// Get light direction
float3 lightDirection = light.position_w - vertexPosition_w;
// Get light distance squared.
float lightDistanceSquared = lengthSquared(lightDirection);
// Get 1/lightDistance
float oneOverLightDistance = rsqrt(lightDistanceSquared);
// Normalize light direction
lightDirection *= oneOverLightDistance;
// compute distance attenuation
float4 attenuationFactors;
attenuationFactors.x = 1.0;
attenuationFactors.y = lightDistanceSquared * oneOverLightDistance;
attenuationFactors.z = lightDistanceSquared;
attenuationFactors.w = 1.0; // oneOverLightDistance;
float distanceAttenuation = 1.0 / dot(light.attenuation, attenuationFactors);
float3 halfAngle = normalize(lightDirection + viewer_w);
float nDotL = dot(normal_w, lightDirection);
float nDotH = dot(normal_w, halfAngle);
float4 lighting = lit(nDotL, nDotH, material.specularPower.x) * distanceAttenuation;
DiffuseSpecular diffuseSpecular;
diffuseSpecular.diffuse = lighting.y * light.diffuseColor;
diffuseSpecular.specular = lighting.z * light.specularColor;
return diffuseSpecular;
}
// ----------------------------------------------------------------------
DiffuseSpecular calculateDiffuseSpecularPointLightWorld(PointSpecularLight light, float3 vertexPosition_w, float3 normal_w)
{
float3 viewer_w = normalize(cameraPosition_w - vertexPosition_w);
// Get light direction
float3 lightDirection = light.position_w - vertexPosition_w;
// Get light distance squared.
float lightDistanceSquared = lengthSquared(lightDirection);
// Get 1/lightDistance
float oneOverLightDistance = rsqrt(lightDistanceSquared);
// Normalize light direction
lightDirection *= oneOverLightDistance;
// compute distance attenuation
float4 attenuationFactors;
attenuationFactors.x = 1.0;
attenuationFactors.y = lightDistanceSquared * oneOverLightDistance;
attenuationFactors.z = lightDistanceSquared;
attenuationFactors.w = 1.0; // oneOverLightDistance;
float distanceAttenuation = 1.0 / dot(light.attenuation, attenuationFactors);
float3 halfAngle = normalize(lightDirection + viewer_w);
float nDotL = dot(normal_w, lightDirection);
float nDotH = dot(normal_w, halfAngle);
float4 lighting = lit(nDotL, nDotH, material.specularPower.x) * distanceAttenuation;
DiffuseSpecular diffuseSpecular;
diffuseSpecular.diffuse = lighting.y * light.diffuseColor;
diffuseSpecular.specular = lighting.z * light.specularColor;
return diffuseSpecular;
}
// ----------------------------------------------------------------------
float4 calculateDiffuseLighting(bool dot3, float4 vertexPosition_o, float3 vertexNormal_o)
{
float4 result = material.emissiveColor;
float3 vertexPosition_w = mul(vertexPosition_o, objectWorldMatrix);
float3 normal_w = normalize(mul(vertexNormal_o, (float3x3)objectWorldMatrix));
if (!dot3)
result += calculateDiffuseParallelHemisphericLight((ParallelLight)lightData.parallelSpecular[0], normal_w, extendedLightData.parallelSpecular[0]);
result += calculateDiffuseParallelLightWorld(lightData.parallel[0], normal_w);
result += calculateDiffuseParallelLightWorld(lightData.parallel[1], normal_w);
result += calculateDiffusePointLight((PointLight)lightData.pointSpecular[0], vertexPosition_w, normal_w);
result += calculateDiffusePointLight(lightData.point[0], vertexPosition_w, normal_w);
result += calculateDiffusePointLight(lightData.point[1], vertexPosition_w, normal_w);
result += calculateDiffusePointLight(lightData.point[2], vertexPosition_w, normal_w);
result += calculateDiffusePointLight(lightData.point[3], vertexPosition_w, normal_w);
return result;
}
// ----------------------------------------------------------------------
DiffuseSpecular calculateDiffuseSpecularTerrainLighting(bool dot3, float4 vertexPosition_o, float3 vertexNormal_o)
{
DiffuseSpecular output;
output.diffuse = 0.0;
output.specular = float4(0.0, 0.0, 0.0, 0.0);
float3 vertexPosition_w = mul(vertexPosition_o, objectWorldMatrix);
float3 normal_w = normalize(mul(vertexNormal_o, (float3x3)objectWorldMatrix));
if (!dot3)
{
DiffuseSpecular temporary = calculateDiffuseSpecularParallelHemisphericLight(lightData.parallelSpecular[0], vertexPosition_w, normal_w, extendedLightData.parallelSpecular[0]);
output.diffuse += temporary.diffuse;
output.specular += temporary.specular;
}
output.diffuse += calculateDiffuseParallelLightWorld(lightData.parallel[0], normal_w);
output.diffuse += calculateDiffuseParallelLightWorld(lightData.parallel[1], normal_w);
DiffuseSpecular temporary = calculateDiffuseSpecularPointLightWorld(lightData.pointSpecular[0], vertexPosition_w, normal_w);
output.diffuse += temporary.diffuse;
output.specular += temporary.specular;
output.diffuse += calculateDiffusePointLight(lightData.point[0], vertexPosition_w, normal_w);
output.diffuse += calculateDiffusePointLight(lightData.point[1], vertexPosition_w, normal_w);
output.diffuse += calculateDiffusePointLight(lightData.point[2], vertexPosition_w, normal_w);
output.diffuse += calculateDiffusePointLight(lightData.point[3], vertexPosition_w, normal_w);
return output;
}
// ----------------------------------------------------------------------
DiffuseSpecular calculateDiffuseSpecularLighting(bool dot3, float4 vertexPosition_o, float3 vertexNormal_o)
{
DiffuseSpecular output;
output.diffuse = material.emissiveColor;
output.specular = float4(0.0, 0.0, 0.0, 0.0);
float3 vertexPosition_w = mul(vertexPosition_o, objectWorldMatrix);
float3 normal_w = normalize(mul(vertexNormal_o, (float3x3)objectWorldMatrix));
if (!dot3)
{
DiffuseSpecular temporary = calculateDiffuseSpecularParallelHemisphericLight(lightData.parallelSpecular[0], vertexPosition_w, normal_w, extendedLightData.parallelSpecular[0]);
output.diffuse += temporary.diffuse;
output.specular += temporary.specular;
}
output.diffuse += calculateDiffuseParallelLightWorld(lightData.parallel[0], normal_w);
output.diffuse += calculateDiffuseParallelLightWorld(lightData.parallel[1], normal_w);
DiffuseSpecular temporary = calculateDiffuseSpecularPointLightWorld(lightData.pointSpecular[0], vertexPosition_w, normal_w);
output.diffuse += temporary.diffuse;
output.specular += temporary.specular;
output.diffuse += calculateDiffusePointLight(lightData.point[0], vertexPosition_w, normal_w);
output.diffuse += calculateDiffusePointLight(lightData.point[1], vertexPosition_w, normal_w);
output.diffuse += calculateDiffusePointLight(lightData.point[2], vertexPosition_w, normal_w);
output.diffuse += calculateDiffusePointLight(lightData.point[3], vertexPosition_w, normal_w);
return output;
}
// ----------------------------------------------------------------------
float2 calculateDiffuseSpecularLightingLookupTextureCoordinates(float4 vertexPosition_o, float vertexNormal_o)
{
float2 result;
// Calculate L.N for light texture lookup
result.x = max(0.0f, dot(lightData.dot3[0].direction_o, vertexNormal_o));
//Calculate H.N for light texture lookup
float3 halfAngle_o = calculateHalfAngle_o(vertexPosition_o);
result.y = max(0.0f, dot(halfAngle_o, vertexNormal_o));
return result;
}
// ======================================================================