cbuffer ConstantBuffer { float4x4 completeTransformation; float4x4 worldTransformation; float4 cameraPosition; float4 lightVector; // the light's vector float4 lightColor; // the light's color float4 ambientColor; // the ambient light's color float4 diffuseCoefficient; // The diffuse reflection cooefficient float4 specularCoefficient; // The specular reflection cooefficient float shininess; // The shininess factor float opacity; // The opacity (transparency) of the material. 0 = fully transparent, 1 = fully opaque // Vars to deal with the water, also padding because the cbuffer needs to be a multiple of 16 float waterHeight; float waterShininess; float4 waterColor; // Padded with a float array, floats being 4 bytes each, the above just hits the multiple of 16 but added extra incase this was the issue, will remove later most likely float padding[4]; } Texture2D BlendMap : register(t0); Texture2DArray TexturesArray : register(t1); // Textures for the water normals and the snow Texture2D WaterNormalMap : register(t2); Texture2D snowTest : register(t3); SamplerState ss { Filter = MIN_MAG_MIP_LINEAR; AddressU = WRAP; AddressV = WRAP; }; struct VertexShaderInput { float3 Position : POSITION; float3 Normal : NORMAL; float2 TexCoord : TEXCOORD0; float2 BlendMapTexCoord : TEXCOORD1; }; struct PixelShaderInput { float4 Position : SV_POSITION; float4 PositionWS: TEXCOORD2; float4 PositionOG: TEXCOORD4; float4 NormalWS : TEXCOORD3; float2 TexCoord : TEXCOORD0; float2 BlendMapTexCoord : TEXCOORD1; }; // Function for rotating a UV around a point float2 UVRotate(float2 uvCoord, float2 pivotPoint, float rotation) { float2x2 rotateMatrix = float2x2(float2(sin(rotation), -cos(rotation)), float2(cos(rotation), sin(rotation))); uvCoord -= pivotPoint; uvCoord = mul(uvCoord, rotateMatrix); uvCoord += pivotPoint; return uvCoord; } // Typical HLSL hasing function for psuedo random number generation float4 hash4(float2 v) { float4 p = mul(float4x2(127.1f, 311.7f, 269.5f, 183.3f, 113.5f, 271.9f, 246.1f, 124.6f), v); return frac(sin(p) * 43758.5453123); } PixelShaderInput VShader(VertexShaderInput vin) { PixelShaderInput output; float3 position = vin.Position; output.PositionOG = output.PositionWS = mul(worldTransformation, float4(position, 1.0f)); output.TexCoord = vin.TexCoord; // Check if the y pos is lower than the water point if (position.y < waterHeight) { // Change up the flat water height with some psuedo RNG height generation float4 yOffset = hash4(float2(-position.y, position.y)); // the offset should return as a value between 0 and 1, i change this to be a value between -1 and 1, then add some height modifier so you can actually see the difference position.y = waterHeight + (((yOffset.y * 2.0f) - 1.0f) * 3.0f); } output.Position = mul(completeTransformation, float4(position, 1.0f)); //output.PositionWS = mul(worldTransformation, float4(position, 1.0f)); output.NormalWS = float4(mul((float3x3)worldTransformation, vin.Normal), 1.0f); output.BlendMapTexCoord = vin.BlendMapTexCoord; return output; } float4 PShader(PixelShaderInput input) : SV_TARGET { float4 directionToCamera = normalize(input.PositionWS - cameraPosition); float4 directionToLight = normalize(-lightVector); float surfaceShininess = shininess; float4 adjustedNormal = normalize(input.NormalWS); if (input.PositionOG.y < waterHeight) { // Sample the normal from the water normal map and calculate it with the worldtransform float4 n0 = WaterNormalMap.Sample(ss, input.TexCoord); float4 n1 = float4((n0.xyz * 2.0f) - 1.0f, 1.0f); //float4 n2 = float4(mul((float3x3)worldTransformation, n0), 1.0f); adjustedNormal = n1; // normalize(n2); surfaceShininess = waterShininess; } // Calculate diffuse lighting float NdotL = max(0, dot(adjustedNormal, directionToLight)); float4 diffuse = saturate(lightColor * NdotL * diffuseCoefficient); diffuse.a = 1.0f; // Calculate specular component float4 R = 2 * NdotL * adjustedNormal - directionToLight; float RdotV = max(0, dot(R, directionToCamera)); float4 specular = saturate(lightColor * pow(RdotV, surfaceShininess) * specularCoefficient); specular.a = 1.0f; // Calculate ambient lighting float4 ambientLight = ambientColor * diffuseCoefficient; float4 color; // Randomly rotate the UV coordinates using the noise map float2 scaleCenter = float2(0.5f, 0.5f); float2 scaledUV = frac(UVRotate(input.TexCoord, scaleCenter, input.BlendMapTexCoord.x)); // (input.TexCoord - scaleCenter) * currentScale + scaleCenter; float2 xChange = ddx(scaledUV); float2 yChange = ddy(scaledUV); /*if (xChange.x < 0) { xChange = float2(0, 0); } if (yChange.y < 0) { yChange = float2(0, 0); }*/ // Sample layers in texture array. float4 c0 = TexturesArray.SampleGrad(ss, float3(scaledUV, 0.0f), xChange, yChange); float4 c1 = TexturesArray.SampleGrad(ss, float3(scaledUV, 1.0f), xChange, yChange); float4 c2 = TexturesArray.SampleGrad(ss, float3(scaledUV, 2.0f), xChange, yChange); float4 c3 = TexturesArray.SampleGrad(ss, float3(scaledUV, 3.0f), xChange, yChange); //float4 c4 = TexturesArray.SampleGrad(ss, float3(scaledUV, 4.0f), xChange, yChange); // Using the single snow texture because of the snow dds loading glitch float4 c4 = snowTest.SampleGrad(ss, float2(scaledUV), xChange, yChange); // Sample the blend map. float4 t = BlendMap.Sample(ss, input.BlendMapTexCoord); // Blend the layers on top of each other. color = c0; color = lerp(color, c1, t.r); color = lerp(color, c2, t.g); color = lerp(color, c3, t.b); color = lerp(color, c4, t.a); // Combine all components, and check if this is water if (input.PositionOG.y < waterHeight) { // Tint the water color = saturate(color) * waterColor; } color = (ambientLight + diffuse) * color; color = saturate(color + specular); return color; }