
Added "Controlled" mesh classes Added Global Lighting Class Added Gamepad controls Split terrain nodes into Height and Perlin classes Fixed Splitmesh node stuff
169 lines
5.4 KiB
HLSL
169 lines
5.4 KiB
HLSL
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);
|
|
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;
|
|
};
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
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, and set the position to it minus a tiny offset because the textures were clipping and causing a weird effect
|
|
if (position.y < waterHeight)
|
|
{
|
|
position.y = waterHeight;
|
|
}
|
|
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 hash4(float2 v)
|
|
{
|
|
float4 p = mul(float4x2(127.1, 311.7, 269.5, 183.3, 113.5, 271.9, 246.1, 124.6), v);
|
|
return frac(sin(p) * 43758.5453123);
|
|
}
|
|
|
|
float4 PShader(PixelShaderInput input) : SV_TARGET
|
|
{
|
|
float4 directionToCamera = normalize(input.PositionWS - cameraPosition);
|
|
float4 directionToLight = normalize(-lightVector);
|
|
float surfaceShininess = shininess;
|
|
float4 adjustedNormal = normalize(input.NormalWS);
|
|
|
|
float currentHeightPer = (waterHeight - input.PositionOG.y) / waterHeight;
|
|
|
|
if (input.PositionOG.y < waterHeight)
|
|
{
|
|
// Sample the normal from the water normal map and calculate it with the worldtransform
|
|
float3 n0 = 2.0f * (float3)WaterNormalMap.Sample(ss, input.TexCoord) - 1.0f;
|
|
float4 n2 = float4(mul((float3x3)worldTransformation, n0), 1.0f);
|
|
adjustedNormal = 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);
|
|
// The noise map is greyscale so we only need to check 1 channel since they should all be the same value
|
|
|
|
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);
|
|
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
|
|
if (input.PositionOG.y < waterHeight)
|
|
{
|
|
// Tint the water
|
|
color = saturate(color) * waterColor;
|
|
}
|
|
color = (ambientLight + diffuse) * color;
|
|
color = saturate(color + specular);
|
|
return color;
|
|
} |