//////////////////////////////////////////////////////////////////////////////////////// // Kara Jensen - mail@karajensen.com - water_hlsl.fx // Based on nvidia Water Shader: http://nvidia.com/shaderlibrary //////////////////////////////////////////////////////////////////////////////////////// cbuffer SceneVertexBuffer : register(b0) { float4x4 viewProjection; float3 cameraPosition; float depthNear; float depthFar; float timer; }; cbuffer ScenePixelBuffer : register(b1) { float3 lightPosition[MAX_LIGHTS]; float3 lightAttenuation[MAX_LIGHTS]; float3 lightDiffuse[MAX_LIGHTS]; float lightActive[MAX_LIGHTS]; }; cbuffer MeshVertexBuffer : register(b2) { float4x4 world; float2 uvScale; float2 bumpScale; float speed; float waveFrequency[MAX_WAVES]; float waveAmplitude[MAX_WAVES]; float wavePhase[MAX_WAVES]; float waveDirectionX[MAX_WAVES]; float waveDirectionZ[MAX_WAVES]; }; cbuffer MeshPixelBuffer : register(b3) { float4 deepColor; float4 shallowColor; float3 reflectionTint; float reflectionIntensity; float3 fresnal; float bumpIntensity; }; SamplerState Sampler; Texture2D DiffuseTexture; Texture2D NormalTexture; TextureCube EnvironmentTexture; struct Attributes { float4 position : SV_POSITION; float3 normal : NORMAL; float depth : TEXCOORD0; float2 uvs : TEXCOORD1; float3 positionWorld : TEXCOORD2; float3 bitangent : TEXCOORD3; float3 tangent : TEXCOORD4; float2 normalUV1 : TEXCOORD5; float2 normalUV2 : TEXCOORD6; float3 vertToCamera : TEXCOORD7; }; struct Outputs { float4 colour : SV_TARGET0; float4 depth : SV_TARGET1; }; Attributes VShader(float4 position : POSITION, float2 uvs : TEXCOORD0) { Attributes output; // Sum the waves together float time = timer * speed; float4 wavePosition = position; float2 waveDerivative = float2(0.0, 0.0); for (int i = 0; i < MAX_WAVES; i++) { // Wave equation: y = a * sin(kx-wt+phase) float2 direction = float2(waveDirectionX[i], waveDirectionZ[i]); float component = dot(direction, position.xz) - (waveFrequency[i] * time) + wavePhase[i]; wavePosition.y += waveAmplitude[i] * sin(component); waveDerivative += waveFrequency[i] * waveAmplitude[i] * cos(component) * direction; } wavePosition = mul(world, wavePosition); output.position = mul(viewProjection, wavePosition); output.positionWorld = wavePosition.xyz; output.uvs = uvs * uvScale; output.normalUV1 = output.uvs * bumpScale.x; output.normalUV2 = output.uvs * bumpScale.y; output.bitangent = float3(1.0, waveDerivative.x, 0.0); output.tangent = float3(0.0, waveDerivative.y, 1.0); output.normal = float3(-waveDerivative.x, 1.0, -waveDerivative.y); output.vertToCamera = cameraPosition - output.positionWorld; output.depth = ((output.position.z - depthNear) * (-1.0 / (depthFar - depthNear))) + 1.0; return output; } Outputs PShader(Attributes input) { float3 diffuseTex = DiffuseTexture.Sample(Sampler, input.uvs).rgb; float3 diffuse = float3(0.0, 0.0, 0.0); float3 normalTex0 = NormalTexture.Sample(Sampler, input.uvs).rgb - 0.5; float3 normalTex1 = NormalTexture.Sample(Sampler, input.normalUV1).rgb - 0.5; float3 normalTex2 = NormalTexture.Sample(Sampler, input.normalUV2).rgb - 0.5; float3 bump = bumpIntensity * (normalTex0 + normalTex1 + normalTex2); float3 normal = normalize(input.normal); float3 bitangent = normalize(input.bitangent); float3 tangent = normalize(input.tangent); normal = normalize(normal + bump.x * tangent + bump.y * bitangent); for (int i = 0; i < MAX_LIGHTS; ++i) { float3 lightColour = lightDiffuse[i]; float3 vertToLight = lightPosition[i] - input.positionWorld; float lightLength = length(vertToLight); float attenuation = 1.0 / (lightAttenuation[i].x + lightAttenuation[i].y * lightLength + lightAttenuation[i].z * lightLength * lightLength); vertToLight /= lightLength; lightColour *= ((dot(vertToLight, normal) + 1.0) * 0.5); diffuse += lightColour * attenuation * lightActive[i]; } // Fresnal Approximation = saturate(bias + scale * pow(1.0 + dot(I,N))) // Reference: NVIDEA CG Chapter 7 Environment Mapping Techniques float3 vertToCamera = normalize(input.vertToCamera); float fresnalFactor = saturate(fresnal.x + fresnal.y * pow(1.0 + dot(-vertToCamera, normal), fresnal.z)); float3 reflection = reflect(-vertToCamera, normal); float4 reflectionTex = EnvironmentTexture.Sample(Sampler, reflection); Outputs output; output.depth = float4(input.depth, input.depth, input.depth, 1.0); output.colour.rgb = diffuseTex * diffuse; output.colour.a = 1.0; output.colour *= (saturate(dot(vertToCamera, normal))*(deepColor-shallowColor))+shallowColor; output.colour.rgb += reflectionTex.rgb * reflectionTint * reflectionIntensity * fresnalFactor; return output; }
//////////////////////////////////////////////////////////////////////////////////////// // Kara Jensen - mail@karajensen.com - water_glsl_vert.fx // Based on nvidia Water Shader: http://nvidia.com/shaderlibrary //////////////////////////////////////////////////////////////////////////////////////// #version 150 in vec4 in_Position; in vec2 in_UVs; out float ex_Depth; out vec2 ex_UVs; out vec3 ex_PositionWorld; out vec3 ex_Normal; out vec3 ex_Tangent; out vec3 ex_Bitangent; out vec3 ex_VertToCamera; out vec2 ex_NormalUV1; out vec2 ex_NormalUV2; uniform float depthNear; uniform float depthFar; uniform float timer; uniform float speed; uniform mat4 world; uniform mat4 viewProjection; uniform vec3 cameraPosition; uniform vec2 uvScale; uniform vec2 bumpScale; uniform float waveFrequency[MAX_WAVES]; uniform float waveAmplitude[MAX_WAVES]; uniform float wavePhase[MAX_WAVES]; uniform float waveDirectionX[MAX_WAVES]; uniform float waveDirectionZ[MAX_WAVES]; void main(void) { // Sum the waves together float time = timer * speed; vec4 wavePosition = in_Position; vec2 waveDerivative = vec2(0.0, 0.0); for (int i = 0; i < MAX_WAVES; i++) { // Wave equation: y = a * sin(kx-wt+phase) vec2 direction = vec2(waveDirectionX[i], waveDirectionZ[i]); float component = dot(direction, in_Position.xz) - (waveFrequency[i] * time) + wavePhase[i]; wavePosition.y += waveAmplitude[i] * sin(component); waveDerivative += waveFrequency[i] * waveAmplitude[i] * cos(component) * direction; } wavePosition = world * wavePosition; gl_Position = viewProjection * wavePosition; ex_PositionWorld = wavePosition.xyz; ex_UVs = in_UVs * uvScale; ex_NormalUV1 = ex_UVs * bumpScale.x; ex_NormalUV2 = ex_UVs * bumpScale.y; ex_Bitangent = vec3(1.0, waveDerivative.x, 0.0); ex_Tangent = vec3(0.0, waveDerivative.y, 1.0); ex_Normal = vec3(-waveDerivative.x, 1.0, -waveDerivative.y); ex_VertToCamera = cameraPosition - ex_PositionWorld; ex_Depth = ((gl_Position.z - depthNear) * (-1.0 / (depthFar - depthNear))) + 1.0; } //////////////////////////////////////////////////////////////////////////////////////// // Kara Jensen - mail@karajensen.com - water_glsl_frag.fx // Based on nvidia Water Shader: http://nvidia.com/shaderlibrary //////////////////////////////////////////////////////////////////////////////////////// #version 150 out vec4 out_Color[SCENE_TEXTURES]; in float ex_Depth; in vec2 ex_UVs; in vec3 ex_PositionWorld; in vec3 ex_Normal; in vec3 ex_Tangent; in vec3 ex_Bitangent; in vec3 ex_VertToCamera; in vec2 ex_NormalUV1; in vec2 ex_NormalUV2; uniform sampler2D DiffuseSampler; uniform sampler2D NormalSampler; uniform samplerCube EnvironmentSampler; uniform vec3 fresnal; uniform float bumpIntensity; uniform vec3 reflectionTint; uniform float reflectionIntensity; uniform vec4 deepColor; uniform vec4 shallowColor; uniform vec3 lightPosition[MAX_LIGHTS]; uniform vec3 lightDiffuse[MAX_LIGHTS]; uniform vec3 lightAttenuation[MAX_LIGHTS]; uniform float lightActive[MAX_LIGHTS]; float saturate(float value) { return clamp(value, 0.0, 1.0); } void main(void) { vec3 diffuseTex = texture(DiffuseSampler, ex_UVs).rgb; vec3 diffuse = vec3(0.0, 0.0, 0.0); vec3 normalTex0 = texture(NormalSampler, ex_UVs).rgb - 0.5; vec3 normalTex1 = texture(NormalSampler, ex_NormalUV1).rgb - 0.5; vec3 normalTex2 = texture(NormalSampler, ex_NormalUV2).rgb - 0.5; vec3 bump = bumpIntensity * (normalTex0 + normalTex1 + normalTex2); vec3 normal = normalize(ex_Normal); vec3 bitangent = normalize(ex_Bitangent); vec3 tangent = normalize(ex_Tangent); normal = normalize(normal + bump.x * tangent + bump.y * bitangent); for (int i = 0; i < MAX_LIGHTS; ++i) { vec3 lightColour = lightDiffuse[i]; vec3 vertToLight = lightPosition[i] - ex_PositionWorld; float lightLength = length(vertToLight); float attenuation = 1.0 / (lightAttenuation[i].x + lightAttenuation[i].y * lightLength + lightAttenuation[i].z * lightLength * lightLength); vertToLight /= lightLength; lightColour *= ((dot(vertToLight, normal) + 1.0) * 0.5); diffuse += lightColour * attenuation * lightActive[i]; } // Fresnal Approximation = saturate(bias + scale * pow(1.0 + dot(I,N))) // Reference: NVIDEA CG Chapter 7 Environment Mapping Techniques vec3 vertToCamera = normalize(ex_VertToCamera); float fresnalFactor = saturate(fresnal.x + fresnal.y * pow(1.0 + dot(-vertToCamera, normal), fresnal.z)); vec3 reflection = reflect(-vertToCamera, normal); vec4 reflectionTex = texture(EnvironmentSampler, reflection); out_Color[ID_COLOUR] = vec4(diffuseTex * diffuse, 1.0); out_Color[ID_COLOUR] *= (saturate(dot(vertToCamera, normal))*(deepColor-shallowColor))+shallowColor; out_Color[ID_COLOUR].rgb += reflectionTex.rgb * reflectionTint * reflectionIntensity * fresnalFactor; out_Color[ID_DEPTH] = vec4(ex_Depth, ex_Depth, ex_Depth, 1.0); }