Torque3D/Templates/Empty/game/shaders/common/water/waterBasicP.hlsl
2012-09-19 11:29:55 -04:00

213 lines
8.2 KiB
HLSL

//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "../torque.hlsl"
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
// miscParams
#define FRESNEL_BIAS miscParams[0]
#define FRESNEL_POWER miscParams[1]
#define CLARITY miscParams[2]
#define ISRIVER miscParams[3]
// reflectParams
#define REFLECT_PLANE_Z reflectParams[0]
#define REFLECT_MIN_DIST reflectParams[1]
#define REFLECT_MAX_DIST reflectParams[2]
#define NO_REFLECT reflectParams[3]
// distortionParams
#define DISTORT_START_DIST distortionParams[0]
#define DISTORT_END_DIST distortionParams[1]
#define DISTORT_FULL_DEPTH distortionParams[2]
// ConnectData.misc
#define LIGHT_VEC IN.misc.xyz
#define WORLD_Z IN.objPos.w
// specularParams
#define SPEC_POWER specularParams[3]
#define SPEC_COLOR specularParams.xyz
//-----------------------------------------------------------------------------
// Structures
//-----------------------------------------------------------------------------
struct ConnectData
{
float4 hpos : POSITION;
// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
float4 rippleTexCoord01 : TEXCOORD0;
// TexCoord 2 for ripple texture lookup
float2 rippleTexCoord2 : TEXCOORD1;
// Screenspace vert position BEFORE wave transformation
float4 posPreWave : TEXCOORD2;
// Screenspace vert position AFTER wave transformation
float4 posPostWave : TEXCOORD3;
// Worldspace unit distance/depth of this vertex/pixel
float pixelDist : TEXCOORD4;
// Objectspace vert position BEFORE wave transformation
// w coord is world space z position.
float4 objPos : TEXCOORD5;
float3 misc : TEXCOORD6;
};
//-----------------------------------------------------------------------------
// approximate Fresnel function
//-----------------------------------------------------------------------------
float fresnel(float NdotV, float bias, float power)
{
return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power);
}
//-----------------------------------------------------------------------------
// Uniforms
//-----------------------------------------------------------------------------
uniform sampler bumpMap : register( S0 );
//uniform sampler2D prepassTex : register( S1 );
uniform sampler2D reflectMap : register( S2 );
uniform sampler refractBuff : register( S3 );
uniform samplerCUBE skyMap : register( S4 );
//uniform sampler foamMap : register( S5 );
uniform float4 baseColor;
uniform float4 miscParams;
uniform float4 reflectParams;
uniform float3 ambientColor;
uniform float3 eyePos;
uniform float3 distortionParams;
uniform float3 fogData;
uniform float4 fogColor;
uniform float4 rippleMagnitude;
uniform float4 specularParams;
uniform float4x4 modelMat;
//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
float4 main( ConnectData IN ) : COLOR
{
// Modulate baseColor by the ambientColor.
float4 waterBaseColor = baseColor * float4( ambientColor.rgb, 1 );
// Get the bumpNorm...
float3 bumpNorm = ( tex2D( bumpMap, IN.rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x;
bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y;
bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z;
bumpNorm = normalize( bumpNorm );
bumpNorm = lerp( bumpNorm, float3(0,0,1), 1.0 - rippleMagnitude.w );
// We subtract a little from it so that we don't
// distort where the water surface intersects the
// camera near plane.
float distortAmt = saturate( IN.pixelDist / 1.0 ) * 0.8;
float4 distortPos = IN.posPostWave;
distortPos.xy += bumpNorm.xy * distortAmt;
#ifdef UNDERWATER
return hdrEncode( tex2Dproj( refractBuff, distortPos ) );
#else
float3 eyeVec = IN.objPos.xyz - eyePos;
eyeVec = mul( (float3x3)modelMat, eyeVec );
float3 reflectionVec = reflect( eyeVec, bumpNorm );
// Color that replaces the reflection color when we do not
// have one that is appropriate.
float4 fakeColor = float4(ambientColor,1);
// Use fakeColor for ripple-normals that are angled towards the camera
eyeVec = -eyeVec;
eyeVec = normalize( eyeVec );
float ang = saturate( dot( eyeVec, bumpNorm ) );
float fakeColorAmt = ang;
// Get reflection map color
float4 refMapColor = hdrDecode( tex2Dproj( reflectMap, distortPos ) );
// If we do not have a reflection texture then we use the cubemap.
refMapColor = lerp( refMapColor, texCUBE( skyMap, reflectionVec ), NO_REFLECT );
// Combine reflection color and fakeColor.
float4 reflectColor = lerp( refMapColor, fakeColor, fakeColorAmt );
//return refMapColor;
// Get refract color
float4 refractColor = hdrDecode( tex2Dproj( refractBuff, distortPos ) );
// calc "diffuse" color by lerping from the water color
// to refraction image based on the water clarity.
float4 diffuseColor = lerp( refractColor, waterBaseColor, 1.0f - CLARITY );
// fresnel calculation
float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER );
//return float4( fresnelTerm.rrr, 1 );
// Also scale the frensel by our distance to the
// water surface. This removes the hard reflection
// when really close to the water surface.
fresnelTerm *= saturate( IN.pixelDist - 0.1 );
// Combine the diffuse color and reflection image via the
// fresnel term and set out output color.
float4 OUT = lerp( diffuseColor, reflectColor, fresnelTerm );
#ifdef WATER_SPEC
// Get some specular reflection.
float3 newbump = bumpNorm;
newbump.xy *= 3.5;
newbump = normalize( bumpNorm );
half3 halfAng = normalize( eyeVec + -LIGHT_VEC );
float specular = saturate( dot( newbump, halfAng ) );
specular = pow( specular, SPEC_POWER );
OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx );
#else // Disable fogging if spec is on because otherwise we run out of instructions.
// Fog it.
float factor = computeSceneFog( eyePos,
IN.objPos,
WORLD_Z,
fogData.x,
fogData.y,
fogData.z );
//OUT.rgb = lerp( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
#endif
return hdrEncode( OUT );
#endif
}