Hello guys,
I have the HLSL shader code below that I use to create a more realistic water effect inside the scene in my game. I am using SamplerCUBE and texCUBE texture to reflect images of surrounding objects so that they can then be reflected onto the surface of the water to create reflection and refraction effects, but I don't understand the code. Is it me or is there a problem with cubic textures that they don't take the reflection of everything around them to reflect back onto the water surface. I'm new to shaders so I hope to get some help from everyone.
This is my shader code:
Code: Select all
float4x4 WorldViewProjection;
float4x4 WorldView;
float4x4 World;
float3 CameraPosition;
float3 ViewDirection;
float4 viewport_size;
float4 light_direction0;
float4 light_diffuse_colour0;
float near_clip_distance;
float far_clip_distance;
sampler2D depthMap : register(s0);
sampler2D noiseMap : register(s1);
samplerCUBE reflectMap : register(s2);
sampler2D refractMap : register(s3);
float2 texRotateScale;
float texDepthFactor;
float wavesSpeed;
float time;
float4 FogColorDensity;
float BigWavesScale;
float SmallWavesScale;
float2 BumpScale;
float ReflectionAmount;
float TransparencyRatio;
float SunShinePow;
float SunMultiplier;
float FresnelBias;
float2 UVScale;
struct VS_IN
{
float4 position : POSITION;
float2 uv0 : TEXCOORD0;
float4 normal : NORMAL;
};
struct VS_OUT
{
float4 oPos : POSITION;
float4 oUV : TEXCOORD0;
float4 oUVScreen : TEXCOORD1;
float3 oEyeDir : TEXCOORD2;
float4 oCamFrontDir : TEXCOORD3;
float4 oPosInView : TEXCOORD4;
float4 oNormal : TEXCOORD5;
};
VS_OUT mainVS(VS_IN input)
{
VS_OUT OUT = (VS_OUT)0;
OUT.oPos = mul(WorldViewProjection, input.position);
OUT.oPosInView = mul(WorldView, input.position);
float4x4 scalemat = float4x4(0.5, 0, 0, 0.5,
0,-0.5, 0, 0.5,
0, 0, 0.5, 0.5,
0, 0, 0, 1);
OUT.oUVScreen = mul(scalemat, OUT.oPos);
OUT.oEyeDir = CameraPosition - input.position.xyz;
OUT.oCamFrontDir = mul(World, ViewDirection);
OUT.oNormal = normalize(mul(WorldView, input.normal));
OUT.oUV = input.uv0.xyxy;
return OUT;
}
float DeviceDepthToEyeLinear(float fDepth, float nearZ, float farZ)
{
float x = (nearZ - farZ) / (farZ * nearZ);
float y = 1.0 / nearZ;
return 1.0 / (x * fDepth + y);
}
float4 mainPS(VS_OUT input): COLOR
{
float2 originUV = input.oUVScreen.xy / input.oUVScreen.w;
float2 texelCenter = (originUV.xy * viewport_size.xy) + float2(0.5, 0.5);
float sceneDepth = tex2D(depthMap, texelCenter.xy * viewport_size.zw).x;
float volumeDepth = min( dot( input.oEyeDir, - input.oCamFrontDir.xyz ) - sceneDepth, 0 );
float waterVolumeFog = 1.0 - exp(volumeDepth* FogColorDensity.w*0.00001);
float2 vTranslation= time.xx * wavesSpeed;
float cosValue = cos(texRotateScale.x);
float sinValue = sin(texRotateScale.x);
float4 vTex = float4( 0, 0, 0, 1 );
vTex.x = texRotateScale.y * (input.oUV.x*cosValue - input.oUV.y*sinValue);
vTex.y = texRotateScale.y * (input.oUV.x*sinValue + input.oUV.y*cosValue);
float4 wave0 = float4(0, 0, 0, 0);
float4 wave1 = float4(0, 0, 0, 0);
wave0.xy = vTex.xy*2*1.0 + vTranslation*2.0;
wave0.wz = vTex.xy*1.0 + vTranslation*3.0;
wave1.xy = vTex.xy*2*2.0 + vTranslation*2.0;
wave1.wz = vTex.xy*2*4.0 + vTranslation*3.0;
float3 eyeDir = normalize(input.oEyeDir);
// cal normal
float3 bumpColorA = half3(0,1,0);
float3 bumpColorB = half3(0,1,0);
float3 bumpColorC = half3(0,1,0);
float3 bumpColorD = half3(0,1,0);
float3 bumpLowFreq = half3(0,1,0);
float3 bumpHighFreq = half3(0,1,0);
// merge big waves
bumpColorA.xz = tex2D(noiseMap, wave0.xy*UVScale).xy;
bumpColorB.xz = tex2D(noiseMap, wave0.wz*UVScale).xy;
bumpLowFreq.xz = (bumpColorA.xz + bumpColorB.xz)*BigWavesScale - BigWavesScale;
// merge small waves
bumpColorC.xz = tex2D(noiseMap, wave1.xy*UVScale).xy;
bumpColorD.xz = tex2D(noiseMap, wave1.wz*UVScale).xy;
bumpHighFreq.xz = (bumpColorC.xz + bumpColorD.xz)*SmallWavesScale - SmallWavesScale;
// merge all waves
float3 bumpNormal = float3(0,1,0);
bumpNormal.xz = bumpLowFreq.xz + bumpHighFreq.xz;
bumpNormal.xyz = normalize( bumpNormal.xyz );
bumpNormal.xz *= BumpScale;
bumpNormal.xyz = normalize( bumpNormal.xyz );
// get Reflection color
float3 reflectDir = (2*dot(eyeDir, bumpNormal)*bumpNormal - eyeDir);
float4 reflectionColour = texCUBE(reflectMap, reflectDir);
// get refraction color
float4 oriColour = tex2D(refractMap, originUV);
float4 refractionColour = tex2D(refractMap, originUV + bumpNormal.xz*0.1);
oriColour.xyz = lerp(oriColour.xyz, FogColorDensity.xyz, waterVolumeFog);
float2 texelCenter2 = ( (originUV + bumpNormal.xz*0.1) * viewport_size.xy) * viewport_size.zw;
float sceneDepth2 = tex2D(depthMap, texelCenter2.xy).x;
sceneDepth2 = DeviceDepthToEyeLinear(sceneDepth2, near_clip_distance, far_clip_distance );
volumeDepth = min( dot( input.oEyeDir, - input.oCamFrontDir.xyz ) - sceneDepth2, 0 );
float waterVolumeFog2 = 1.0 - exp(volumeDepth* FogColorDensity.w*0.00001);
refractionColour.xyz = lerp(refractionColour.xyz, FogColorDensity.xyz, waterVolumeFog2);
// cal fresnel
float vdn = abs(dot(eyeDir, bumpNormal));
float fresnel = saturate(FresnelBias + (1-FresnelBias)*pow(1 - vdn, 5));
float4 finalColor = lerp(refractionColour, reflectionColour * ReflectionAmount, fresnel * TransparencyRatio);
// use sun shine
light_direction0 = float4(1.0, 0.0, 1.0, 0.0);
light_diffuse_colour0 = float4(1.0, 1.0, 1.0, 1.0);
float RdoTL = saturate(dot(reflectDir, -light_direction0.xyz));
float sunSpecular = pow( RdoTL , SunShinePow );
float3 vSunGlow = sunSpecular * light_diffuse_colour0.xyz * SunMultiplier;
finalColor.xyz += vSunGlow;
float4 OutColor;
OutColor.xyz = lerp(finalColor.xyz, oriColour.xyz, saturate(waterVolumeFog * texDepthFactor));
OutColor.w = 1;
return OutColor;
}
This is the content in my *.program file
Code: Select all
vertex_program WaterReflectionRefraction_VS hlsl
{
source WaterReflectionRefraction.hlsl
entry_point mainVS
target vs_3_0
default_params
{
param_named_auto WorldViewProjection worldviewproj_matrix
param_named_auto WorldView worldview_matrix
param_named_auto World world_matrix
param_named_auto CameraPosition camera_position_object_space
param_named_auto ViewDirection view_direction
}
}
fragment_program WaterReflectionRefraction_PS hlsl
{
source WaterReflectionRefraction.hlsl
entry_point mainPS
target ps_3_0
default_params
{
param_named_auto viewport_size viewport_size
param_named_auto near_clip_distance near_clip_distance
param_named_auto far_clip_distance far_clip_distance
param_named_auto time time 1
param_named texRotateScale float2 8 11
param_named texDepthFactor float 50
param_named FogColorDensity float4 0.5 0.7 0.9 5000
param_named wavesSpeed float 0.2
param_named BigWavesScale float 0.9
param_named SmallWavesScale float 0.1
param_named BumpScale float2 0.45 0.15
param_named UVScale float2 0.02 0.05
param_named FresnelBias float 2.5
param_named TransparencyRatio float 0.0
param_named ReflectionAmount float 0.2
param_named SunShinePow float 0.12
param_named SunMultiplier float 0.15
}
}
This is material that will call shader
Code: Select all
material suzhou_water
{
technique
{
pass
{
depth_write off
vertex_program_ref WaterReflectionRefraction_VS
{
}
fragment_program_ref WaterReflectionRefraction_PS
{
}
texture_unit
{
tex_address_mode clamp
filtering none
}
texture_unit
{
texture oceanwaves.dds 2d
filtering trilinear
}
texture_unit
{
texture Water_Cubicmap.dds cubic
}
texture_unit
{
tex_address_mode clamp
filtering none
}
}
}
}
This is GpuProgramParameters in orge
Code: Select all
GpuProgramParameters::AutoConstantDefinition GpuProgramParameters::AutoConstantDictionary[] = {
AutoConstantDefinition(ACT_WORLD_MATRIX, "world_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_WORLD_MATRIX, "inverse_world_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_TRANSPOSE_WORLD_MATRIX, "transpose_world_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLD_MATRIX, "inverse_transpose_world_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_WORLD_MATRIX_ARRAY_3x4, "world_matrix_array_3x4", 12, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_WORLD_MATRIX_ARRAY, "world_matrix_array", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_VIEW_MATRIX, "view_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_VIEW_MATRIX, "inverse_view_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_TRANSPOSE_VIEW_MATRIX, "transpose_view_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_VIEW_MATRIX, "inverse_transpose_view_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_PROJECTION_MATRIX, "projection_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_PROJECTION_MATRIX, "inverse_projection_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_TRANSPOSE_PROJECTION_MATRIX, "transpose_projection_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_PROJECTION_MATRIX, "inverse_transpose_projection_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_VIEWPROJ_MATRIX, "viewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_VIEWPROJ_MATRIX, "inverse_viewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_TRANSPOSE_VIEWPROJ_MATRIX, "transpose_viewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_VIEWPROJ_MATRIX, "inverse_transpose_viewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_WORLDVIEW_MATRIX, "worldview_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_WORLDVIEW_MATRIX, "inverse_worldview_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_TRANSPOSE_WORLDVIEW_MATRIX, "transpose_worldview_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLDVIEW_MATRIX, "inverse_transpose_worldview_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_WORLDVIEWPROJ_MATRIX, "worldviewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_WORLDVIEWPROJ_MATRIX, "inverse_worldviewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_TRANSPOSE_WORLDVIEWPROJ_MATRIX, "transpose_worldviewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_TRANSPOSE_WORLDVIEWPROJ_MATRIX, "inverse_transpose_worldviewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_RENDER_TARGET_FLIPPING, "render_target_flipping", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_FOG_COLOUR, "fog_colour", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_FOG_PARAMS, "fog_params", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_SURFACE_AMBIENT_COLOUR, "surface_ambient_colour", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_SURFACE_DIFFUSE_COLOUR, "surface_diffuse_colour", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_SURFACE_SPECULAR_COLOUR, "surface_specular_colour", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_SURFACE_EMISSIVE_COLOUR, "surface_emissive_colour", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_SURFACE_SHININESS, "surface_shininess", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_DERIVED_AMBIENT_LIGHT_COLOUR, "derived_ambient_light_colour", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_DERIVED_LIGHT_DIFFUSE_COLOUR, "derived_light_diffuse_colour", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_DERIVED_LIGHT_SPECULAR_COLOUR, "derived_light_specular_colour", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_DERIVED_SCENE_COLOUR, "derived_scene_colour", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_AMBIENT_LIGHT_COLOUR, "ambient_light_colour", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_LIGHT_DIFFUSE_COLOUR, "light_diffuse_colour", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_SPECULAR_COLOUR, "light_specular_colour", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_ATTENUATION, "light_attenuation", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_POSITION, "light_position", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_POSITION_OBJECT_SPACE, "light_position_object_space", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_POSITION_VIEW_SPACE, "light_position_view_space", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_DIRECTION, "light_direction", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_DIRECTION_OBJECT_SPACE, "light_direction_object_space", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_DIRECTION_VIEW_SPACE, "light_direction_view_space", 4, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_DISTANCE_OBJECT_SPACE, "light_distance_object_space", 1, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_LIGHT_POWER_SCALE, "light_power", 1, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_SHADOW_EXTRUSION_DISTANCE, "shadow_extrusion_distance", 1, ET_REAL, ACDT_INT),
AutoConstantDefinition(ACT_CAMERA_POSITION, "camera_position", 3, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_CAMERA_POSITION_OBJECT_SPACE, "camera_position_object_space", 3, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_TEXTURE_VIEWPROJ_MATRIX, "texture_viewproj_matrix", 16, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_CUSTOM, "custom", 4, ET_REAL, ACDT_INT), // *** needs to be tested
AutoConstantDefinition(ACT_TIME, "time", 1, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TIME_0_X, "time_0_x", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_COSTIME_0_X, "costime_0_x", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_SINTIME_0_X, "sintime_0_x", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TANTIME_0_X, "tantime_0_x", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TIME_0_X_PACKED, "time_0_x_packed", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TIME_0_1, "time_0_1", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_COSTIME_0_1, "costime_0_1", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_SINTIME_0_1, "sintime_0_1", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TANTIME_0_1, "tantime_0_1", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TIME_0_1_PACKED, "time_0_1_packed", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TIME_0_2PI, "time_0_2pi", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_COSTIME_0_2PI, "costime_0_2pi", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_SINTIME_0_2PI, "sintime_0_2pi", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TANTIME_0_2PI, "tantime_0_2pi", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_TIME_0_2PI_PACKED, "time_0_2pi_packed", 4, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_FRAME_TIME, "frame_time", 1, ET_REAL, ACDT_REAL),
AutoConstantDefinition(ACT_FPS, "fps", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_VIEWPORT_WIDTH, "viewport_width", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_VIEWPORT_HEIGHT, "viewport_height", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_VIEWPORT_WIDTH, "inverse_viewport_width", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_INVERSE_VIEWPORT_HEIGHT, "inverse_viewport_height", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_VIEWPORT_SIZE, "viewport_size", 4, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_VIEW_DIRECTION, "view_direction", 3, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_VIEW_SIDE_VECTOR, "view_side_vector", 3, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_VIEW_UP_VECTOR, "view_up_vector", 3, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_FOV, "fov", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_NEAR_CLIP_DISTANCE, "near_clip_distance", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_FAR_CLIP_DISTANCE, "far_clip_distance", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_PASS_NUMBER, "pass_number", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_PASS_ITERATION_NUMBER, "pass_iteration_number", 1, ET_REAL, ACDT_NONE),
AutoConstantDefinition(ACT_ANIMATION_PARAMETRIC, "animation_parametric", 4, ET_REAL, ACDT_INT),
};
This is the dds file that I uesed in my material