├── README.md ├── deffiles └── materials │ └── _ocean.template ├── model_export └── shader-ocean │ └── ocean_plane.xmodel_export ├── raw ├── shader_bin │ └── shader_src │ │ ├── lib │ │ ├── ocean_utility.hlsl │ │ ├── transform.hlsl │ │ └── utility.hlsl │ │ ├── ps_3_0_worldfx_ocean.hlsl │ │ ├── ps_3_0_worldfx_ocean_unlit.hlsl │ │ ├── shader_vars.h │ │ ├── vs_3_0_worldfx_ocean.hlsl │ │ └── vs_3_0_worldfx_ocean_unlit.hlsl ├── statemaps │ └── water.sm ├── techniques │ ├── worldfx_ocean.tech │ └── worldfx_ocean_unlit.tech └── techsets │ ├── mc_worldfx_ocean.techset │ ├── sm2 │ ├── mc_worldfx_ocean.techset │ ├── wc_worldfx_ocean.techset │ └── worldfx_ocean.techset │ ├── wc_worldfx_ocean.techset │ └── worldfx_ocean.techset ├── source_data └── shader_ocean.gdt └── texture_assets └── shader_ocean ├── surf_ocean_cube_bk.tga ├── surf_ocean_cube_dn.tga ├── surf_ocean_cube_ft.tga ├── surf_ocean_cube_lf.tga ├── surf_ocean_cube_rt.tga ├── surf_ocean_cube_up.tga ├── surf_ocean_foam_as_spec.tga ├── surf_ocean_height_as_cosine.tga └── surf_ocean_normal.tga /README.md: -------------------------------------------------------------------------------- 1 | ## A Call of Duty 4 - Realtime / dynamic ocean shader, fully customizable in-game via the use of the IW3xo client 2 | 3 | ![](https://xoxor4d.github.io/assets/img/shader-ocean/prev03.jpg) 4 | 5 |

6 | 7 | 8 |

9 | 10 | #### Using the shader: 11 | 1. Clone the repo or download as zip 12 | 2. Copy all files into the cod4 root directory 13 | 3. Open the "shader_ocean.gdt" in Asset Manager, compile the material and the xmodel 14 | 4. Compile shaders, "worldfx_ocean" and "worldfx_ocean_unlit" by either using https://xoxor4d.github.io/projects/cod4-compileTools/ or shader_tool directly (https://xoxor4d.github.io/tutorials/hlsl-intro/#compiling) 15 | 5. Place the "ocean_plane" xmodel into your map or apply the material to any other kind of xmodel/terrain patch 16 | 6. Tweak in-game using IW3xo (The shader ships with in-game tweaking enabled, requiring IW3xo to be used, see below to disable this if needed) 17 | 18 | #### Tweaking in-game using the GUI: 19 | 1. Use IW3xo and the built in command "/devgui" -> ocean tab to tweak the shader however you like. Use the export button to export your settings. (root/iw3xo/shader_settings/ocean_settings.txt) 20 | 2. Overwrite the static shader constants inside the __#else block__ (if __USE_CUSTOM_CONSTANTS__ is not defined) in both the vertex and pixelshader. Note that both are sharing 3 of the exported constants. 21 | 3. The shader ships with in-game tweaking enabled, requiring IW3xo to be used. This can be disabled by commenting "//" __#define USE_CUSTOM_CONSTANTS__ in both the vertex and pixelshader. 22 | 4. Disabling __USE_CUSTOM_CONSTANTS__ will enable vanilla cod4 usage. You have to do this before you ship your mod/map. 23 | 24 | #### Tweaking in-game using an addon fastfile: 25 | - IW3xo supports loading/reloading of fastfiles and its assets in-game 26 | - Expecting that you already have the shader up and running in your map/mod, do the following: 27 | - Include the following in your fastfile zone: 28 | 29 | > material,dynamic_ocean 30 | > techset,mc_worldfx_ocean 31 | > techset,wc_worldfx_ocean 32 | > techset,worldfx_ocean 33 | 34 | - Modify the shader and recompile it 35 | - Build the fastfile 36 | - Load up your map/mod thats including the ocean shader 37 | - Use the following command to load your zone file: "/loadzone your_zone_name" 38 | - The ocean shader should now reflect your changes 39 | - Rinse and repeat 40 | 41 | #### Note: 42 | - Flat plane models with lots of vertices work best (for obvious reasons) 43 | - The shader was written to be used with models. It does however work with terrain patches and alike. It just wont look as good. 44 | - Duplicate shader files and assign them to a new material if you need different settings for different enviroments 45 | - The _unlit variant will be used in radiant or in-game when r_fullbright is turned on. Please note that the _unlit variant does not support custom shader constants, meaning it cannot be controlled in-game. (use to the addon fastfile method instead) 46 | 47 | ___ 48 | 49 | Project Page: 50 | https://xoxor4d.github.io/projects/cod4-ocean/ 51 | 52 | IW3xo: 53 | https://xoxor4d.github.io/projects/iw3xo/ 54 | 55 | Custom CoD4 Compiletools: 56 | https://xoxor4d.github.io/projects/cod4-compileTools/ 57 | 58 | Discord: 59 | https://discord.gg/t5jRGbj 60 | 61 | ## Credits 62 | - https://github.com/tuxalin/water-shader 63 | 64 | ___ 65 | 66 | [![Play](https://xoxor4d.github.io/assets/img/shader-ocean/vid01.jpg)](https://www.youtube.com/watch?v=0lDc3uzDOD4) 67 | -------------------------------------------------------------------------------- /deffiles/materials/_ocean.template: -------------------------------------------------------------------------------- 1 | // * xoxor4d.github.io/projects/cod4-ocean/ 2 | // * original shader : https://github.com/tuxalin/water-shader 3 | 4 | #include "commonsetup.template" 5 | 6 | #if "@customString@" != "" 7 | techniqueSet( "@customString@" ); 8 | #else 9 | #error " cannot be empty! Define the techset (without prefix/extension) that you want to use for your material!" 10 | #endif 11 | 12 | textureTable 13 | { 14 | #if "$colorMap$" != "" 15 | "colorMap" = cubemap( "no tile", "@filterColor@", "$colorMap$", @nopicmipColor@ ) "@formatColor@" : "colorMap"; 16 | #else 17 | #error "missing cubeMap for reflection/radiance!" 18 | #endif 19 | 20 | #if "$normalMap$" == "" 21 | #error "missing water normal map!" 22 | #endif 23 | "normalMap" = map( "@tileColor@", "@filterColor@", "$normalMap$", @nopicmipColor@ ) "@formatColor@" : "normalMap"; 24 | 25 | #if "$specColorMap$" == "" 26 | #error "missing foam (rgb)" 27 | #endif 28 | "specularMap" = map( "@tileColor@", "@filterColor@", "$specColorMap$", @nopicmipColor@ ) "@formatColor@" : "specularMap"; 29 | } 30 | 31 | refCubeImage( "$colorMap$" ); -------------------------------------------------------------------------------- /raw/shader_bin/shader_src/lib/ocean_utility.hlsl: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // normal calculations 4 | // 5 | 6 | float3 UnpackNormal(float4 n) 7 | { 8 | n.xyz = n.xyz * 2.0 - 1.0; 9 | return n.xyz; 10 | } 11 | 12 | float3 UnpackNormalRecZ(float4 packednormal) 13 | { 14 | float3 normal; 15 | normal.xy = packednormal.wy * 2 - 1; 16 | normal.z = sqrt(1 - normal.x*normal.x - normal.y * normal.y); 17 | return normal; 18 | } 19 | 20 | // Project the surface gradient (dhdx, dhdy) onto the surface (n, dpdx, dpdy). 21 | float3 ComputeSurfaceGradient(float3 n, float3 dpdx, float3 dpdy, float dhdx, float dhdy) 22 | { 23 | float3 r1 = cross(dpdy, n); 24 | float3 r2 = cross(n, dpdx); 25 | 26 | return (r1 * dhdx + r2 * dhdy) / dot(dpdx, r1); 27 | } 28 | 29 | // Move the normal away from the surface normal in the opposite surface gradient direction. 30 | float3 PerturbNormal(float3 n, float3 dpdx, float3 dpdy, float dhdx, float dhdy) 31 | { 32 | return normalize(n - ComputeSurfaceGradient(n, dpdx, dpdy, dhdx, dhdy)); 33 | } 34 | 35 | // Returns the surface normal using screen-space partial derivatives of the height field. 36 | float3 ComputeSurfaceNormal(float3 position, float3 normal, float height) 37 | { 38 | float3 dpdx = ddx(position); 39 | float3 dpdy = ddy(position); 40 | 41 | float dhdx = ddx(height); 42 | float dhdy = ddy(height); 43 | 44 | return PerturbNormal(normal, dpdx, dpdy, dhdx, dhdy); 45 | } 46 | 47 | float ApplyChainRule(float dhdu, float dhdv, float dud_, float dvd_) 48 | { 49 | return dhdu * dud_ + dhdv * dvd_; 50 | } 51 | 52 | // Calculate the surface normal using the uv-space gradient (dhdu, dhdv) 53 | // Requires height field gradient, double storage. 54 | float3 CalculateSurfaceNormal(float3 position, float3 normal, float2 gradient, float2 duvdx, float2 duvdy) 55 | { 56 | float3 dpdx = ddx(position); 57 | float3 dpdy = ddy(position); 58 | 59 | float dhdx = ApplyChainRule(gradient.x, gradient.y, duvdx.x, duvdx.y); 60 | float dhdy = ApplyChainRule(gradient.x, gradient.y, duvdy.x, duvdy.y); 61 | 62 | return PerturbNormal(normal, dpdx, dpdy, dhdx, dhdy); 63 | } 64 | 65 | // Returns the surface normal using screen-space partial derivatives of world position. 66 | // Will result in hard shading normals. 67 | float3 ComputeSurfaceNormal(float3 position) 68 | { 69 | return normalize(cross(ddx(position), ddy(position))); 70 | } 71 | 72 | // portability reasons 73 | float3 mul2x3(float2 val, float3 row1, float3 row2) 74 | { 75 | float3 res; 76 | for (int i = 0; i < 3; i++) 77 | { 78 | float2 col = float2(row1[i], row2[i]); 79 | res[i] = dot(val, col); 80 | } 81 | 82 | return res; 83 | } 84 | 85 | float3 ComputeSurfaceNormal(float3 normal, float3 tangent, float3 bitangent, sampler2D tex, float2 uv) 86 | { 87 | float3x3 tangentFrame = float3x3(normalize(bitangent), normalize(tangent), normal); 88 | 89 | #ifndef USE_FILTERING 90 | normal = UnpackNormal(tex2D(tex, uv)); 91 | #else 92 | float2 duv1 = ddx(uv) * 2; 93 | float2 duv2 = ddy(uv) * 2; 94 | normal = UnpackNormal(tex2Dgrad(tex, uv, duv1, duv2)); 95 | #endif 96 | return normalize(mul(normal, tangentFrame)); 97 | } 98 | 99 | float3x3 ComputeTangentFrame(float3 normal, float3 position, float2 uv) 100 | { 101 | float3 dp1 = ddx(position); 102 | float3 dp2 = ddy(position); 103 | float2 duv1 = ddx(uv); 104 | float2 duv2 = ddy(uv); 105 | 106 | float3x3 M = float3x3(dp1, dp2, cross(dp1, dp2)); 107 | float3 inverseM1 = float3(cross(M[1], M[2])); 108 | float3 inverseM2 = float3(cross(M[2], M[0])); 109 | float3 T = mul2x3(float2(duv1.x, duv2.x), inverseM1, inverseM2); 110 | float3 B = mul2x3(float2(duv1.y, duv2.y), inverseM1, inverseM2); 111 | 112 | return float3x3(normalize(T), normalize(B), normal); 113 | } 114 | 115 | // Returns the surface normal using screen-space partial derivatives of the uv and position coordinates. 116 | float3 ComputeSurfaceNormal(float3 normal, float3 position, sampler2D tex, float2 uv) 117 | { 118 | float3x3 tangentFrame = ComputeTangentFrame(normal, position, uv); 119 | 120 | #ifndef USE_FILTERING 121 | normal = UnpackNormal(tex2D(tex, uv)); 122 | #else 123 | float2 duv1 = ddx(uv) * 2; 124 | float2 duv2 = ddy(uv) * 2; 125 | normal = UnpackNormal(tex2Dgrad(tex, uv, duv1, duv2)); 126 | #endif 127 | return normalize(mul(normal, tangentFrame)); 128 | } 129 | 130 | float3 ComputeNormal(float4 heights, float strength) 131 | { 132 | float hL = heights.x; 133 | float hR = heights.y; 134 | float hD = heights.z; 135 | float hT = heights.w; 136 | 137 | float3 normal = float3(hL - hR, strength, hD - hT); 138 | return normalize(normal); 139 | } 140 | 141 | float3 ComputeNormal(sampler2D tex, float2 uv, float texelSize, float strength) // ---------------------------------------------------------------------------------------------- hm was missing .x .y .z .w 142 | { 143 | float3 off = float3(texelSize, texelSize, 0.0); 144 | float4 heights; 145 | heights.x = tex2D(tex, uv.xy - off.xz).x; // hL 146 | heights.y = tex2D(tex, uv.xy + off.xz).y; // hR 147 | heights.z = tex2D(tex, uv.xy - off.zy).z; // hD 148 | heights.w = tex2D(tex, uv.xy + off.zy).w; // hT 149 | 150 | return ComputeNormal(heights, strength); 151 | } 152 | 153 | 154 | 155 | 156 | // 157 | // depth refraction 158 | // 159 | 160 | // waterTransparency - x = , y = water visibility along eye vector, 161 | // waterDepthValues - x = water depth in world space, y = view/accumulated water depth in world space 162 | half3 DepthRefraction(float2 waterTransparency, float2 waterDepthValues, float shoreRange, float3 horizontalExtinction, 163 | half3 refractionColor, half3 shoreColor, half3 surfaceColor, half3 depthColor) 164 | { 165 | float waterClarity = waterTransparency.x; 166 | float visibility = waterTransparency.y; 167 | float waterDepth = waterDepthValues.x; 168 | float viewWaterDepth = waterDepthValues.y; 169 | 170 | float accDepth = viewWaterDepth * waterClarity; // accumulated water depth 171 | float accDepthExp = saturate(accDepth / (2.5 * visibility)); 172 | accDepthExp *= (1.0 - accDepthExp) * accDepthExp * accDepthExp + 1; // out cubic 173 | 174 | surfaceColor = lerp(shoreColor, surfaceColor, saturate(waterDepth / shoreRange)); 175 | half3 waterColor = lerp(surfaceColor, depthColor, saturate(waterDepth / horizontalExtinction)); 176 | 177 | refractionColor = lerp(refractionColor, surfaceColor * waterColor, saturate(accDepth / visibility)); 178 | refractionColor = lerp(refractionColor, depthColor, accDepthExp); 179 | refractionColor = lerp(refractionColor, depthColor * waterColor, saturate(waterDepth / horizontalExtinction)); 180 | return refractionColor; 181 | } 182 | 183 | 184 | 185 | // 186 | // snoise 187 | // 188 | 189 | float3 mod289(float3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } 190 | float2 mod289(float2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } 191 | float3 permute(float3 x) { return mod289(((x*34.0) + 1.0)*x); } 192 | 193 | float snoise(float2 v) 194 | { 195 | // Precompute values for skewed triangular grid 196 | const float4 C = float4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 197 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) 198 | -0.577350269189626, // -1.0 + 2.0 * C.x 199 | 0.024390243902439 // 1.0 / 41.0 200 | ); 201 | 202 | 203 | // First corner (x0) 204 | float2 i = floor(v + dot(v, C.yy)); 205 | float2 x0 = v - i + dot(i, C.xx); 206 | 207 | // Other two corners (x1, x2) 208 | float2 i1; 209 | i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0); 210 | float2 x1 = x0.xy + C.xx - i1; 211 | float2 x2 = x0.xy + C.zz; 212 | 213 | // Do some permutations to avoid 214 | // truncation effects in permutation 215 | i = mod289(i); 216 | float3 p = permute( 217 | permute(i.y + float3(0.0, i1.y, 1.0)) 218 | + i.x + float3(0.0, i1.x, 1.0)); 219 | 220 | float3 m = max(0.5 - float3( 221 | dot(x0, x0), 222 | dot(x1, x1), 223 | dot(x2, x2) 224 | ), 0.0); 225 | 226 | m = m*m; 227 | m = m*m; 228 | 229 | // Gradients: 230 | // 41 pts uniformly over a line, mapped onto a diamond 231 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) 232 | 233 | float3 x = 2.0 * frac(p * C.www) - 1.0; 234 | float3 h = abs(x) - 0.5; 235 | float3 ox = floor(x + 0.5); 236 | float3 a0 = x - ox; 237 | 238 | // Normalise gradients implicitly by scaling m 239 | // Approximation of: m *= inversesqrt(a0*a0 + h*h); 240 | m *= 1.79284291400159 - 0.85373472095314 *(a0*a0 + h*h); 241 | 242 | // Compute final noise value at P 243 | float3 g; 244 | g.x = a0.x * x0.x + h.x * x0.y; 245 | g.yz = a0.yz * float2(x1.x, x2.x) + h.yz * float2(x1.y, x2.y); 246 | return 130.0 * dot(m, g); 247 | } 248 | 249 | 250 | 251 | // 252 | // waves 253 | // 254 | 255 | float3 GerstnerWaveValues(float2 position, float2 D, float amplitude, float wavelength, float Q, float timer) 256 | { 257 | float w = 2 * 3.14159265 / wavelength; 258 | float dotD = dot(position, D); 259 | float v = w * dotD + timer; 260 | return float3(cos(v), sin(v), w); 261 | } 262 | 263 | half3 GerstnerWaveNormal(float2 D, float A, float Q, float3 vals) 264 | { 265 | half C = vals.x; 266 | half S = vals.y; 267 | half w = vals.z; 268 | half WA = w * A; 269 | half WAC = WA * C; 270 | half3 normal = half3(-D.x * WAC, 1.0 - Q * WA * S, -D.y * WAC); 271 | return normalize(normal); 272 | } 273 | 274 | half3 GerstnerWaveTangent(float2 D, float A, float Q, float3 vals) 275 | { 276 | half C = vals.x; 277 | half S = vals.y; 278 | half w = vals.z; 279 | half WA = w * A; 280 | half WAS = WA * S; 281 | half3 normal = half3(Q * -D.x * D.y * WAS, D.y * WA * C, 1.0 - Q * D.y * D.y * WAS); 282 | return normalize(normal); 283 | } 284 | 285 | float3 GerstnerWaveDelta(float2 D, float A, float Q, float3 vals) 286 | { 287 | float C = vals.x; 288 | float S = vals.y; 289 | float QAC = Q * A * C; 290 | return float3(QAC * D.x, A * S, QAC * D.y); 291 | } 292 | 293 | void GerstnerWave(float2 windDir, float tiling, float amplitude, float wavelength, float Q, float timer, inout float3 position, out half3 normal) 294 | { 295 | float2 D = windDir; 296 | float3 vals = GerstnerWaveValues(position.xz * tiling, D, amplitude, wavelength, Q, timer); 297 | normal = GerstnerWaveNormal(D, amplitude, Q, vals); 298 | position += GerstnerWaveDelta(D, amplitude, Q, vals); 299 | } 300 | 301 | float3 SineWaveValues(float2 position, float2 D, float amplitude, float wavelength, float timer) 302 | { 303 | float w = 2 * 3.14159265 / wavelength; 304 | float dotD = dot(position, D); 305 | float v = w * dotD + timer; 306 | return float3(cos(v), sin(v), w); 307 | } 308 | 309 | half3 SineWaveNormal(float2 D, float A, float3 vals) 310 | { 311 | half C = vals.x; 312 | half w = vals.z; 313 | half WA = w * A; 314 | half WAC = WA * C; 315 | half3 normal = half3(-D.x * WAC, 1.0, -D.y * WAC); 316 | return normalize(normal); 317 | } 318 | 319 | half3 SineWaveTangent(float2 D, float A, float3 vals) 320 | { 321 | half C = vals.x; 322 | half w = vals.z; 323 | half WAC = w * A * C; 324 | half3 normal = half3(0.0, D.y * WAC, 1.0); 325 | return normalize(normal); 326 | } 327 | 328 | float SineWaveDelta(float A, float3 vals) 329 | { 330 | return vals.y * A; 331 | } 332 | 333 | void SineWave(float2 windDir, float tiling, float amplitude, float wavelength, float timer, inout float3 position, out half3 normal) 334 | { 335 | float2 D = windDir; 336 | float3 vals = SineWaveValues(position.xz * tiling, D, amplitude, wavelength, timer); 337 | normal = SineWaveNormal(D, amplitude, vals); 338 | position.y += SineWaveDelta(amplitude, vals); 339 | } 340 | 341 | 342 | 343 | // 344 | // displacement 345 | // 346 | 347 | float2 GetNoise(in float2 position, in float2 timedWindDir) 348 | { 349 | float2 noise; 350 | noise.x = snoise(position * 0.015 + timedWindDir * 0.0005); // large and slower noise 351 | noise.y = snoise(position * 0.1 + timedWindDir * 0.002); // smaller and faster noise 352 | return saturate(noise); 353 | } 354 | 355 | void AdjustWavesValues(in float2 noise, inout half4 wavesNoise, inout half4 wavesIntensity) 356 | { 357 | wavesNoise = wavesNoise * half4(noise.y * 0.25, noise.y * 0.25, noise.x + noise.y, noise.y); 358 | wavesIntensity = wavesIntensity + half4(saturate(noise.y - noise.x), noise.x, noise.y, noise.x + noise.y); 359 | wavesIntensity = clamp(wavesIntensity, 0.01, 10); 360 | } 361 | 362 | // uv in texture space, normal in world space 363 | half3 ComputeNormal(sampler2D normalTexture, float2 worldPos, float2 texCoord, half3 normal, half3 tangent, half3 bitangent, half4 wavesNoise, half4 wavesIntensity, float2 timedWindDir) 364 | { 365 | float2 noise = GetNoise(worldPos, timedWindDir * 0.5); 366 | 367 | // the fuck 368 | //AdjustWavesValues(noise, wavesNoise, wavesIntensity); 369 | 370 | float2 texCoords[4] = { texCoord * 1.6 + timedWindDir * 0.064 + wavesNoise.x, 371 | texCoord * 0.8 + timedWindDir * 0.032 + wavesNoise.y, 372 | texCoord * 0.5 + timedWindDir * 0.016 + wavesNoise.z, 373 | texCoord * 0.3 + timedWindDir * 0.008 + wavesNoise.w }; 374 | 375 | half3 wavesNormal = half3(0, 1, 0); 376 | //#ifdef USE_DISPLACEMENT 377 | normal = normalize(normal); 378 | tangent = normalize(tangent); 379 | bitangent = normalize(bitangent); 380 | for (int i = 0; i < 4; ++i) 381 | { 382 | wavesNormal += ComputeSurfaceNormal(normal, tangent, bitangent, normalTexture, texCoords[i]) * wavesIntensity[i]; 383 | } 384 | 385 | //wavesNormal = wavesNormal * 4; 386 | //#else 387 | /* for (int i = 0; i < 4; ++i) 388 | { 389 | wavesNormal += UnpackNormal(tex2D(normalTexture, texCoords[i])) * wavesIntensity[i]; 390 | } 391 | wavesNormal.xyz = wavesNormal.xzy; // flip zy to avoid btn multiplication */ 392 | //#endif // #ifdef USE_DISPLACEMENT 393 | 394 | return wavesNormal; 395 | } 396 | 397 | #ifdef USE_DISPLACEMENT 398 | float ComputeNoiseHeight(sampler2D heightTexture, float4 wavesIntensity, float4 wavesNoise, float2 texCoord, float2 noise, float2 timedWindDir) 399 | { 400 | AdjustWavesValues(noise, wavesNoise, wavesIntensity); 401 | 402 | float2 texCoords[4] = { texCoord * 1.6 + timedWindDir * 0.064 + wavesNoise.x, 403 | texCoord * 0.8 + timedWindDir * 0.032 + wavesNoise.y, 404 | texCoord * 0.5 + timedWindDir * 0.016 + wavesNoise.z, 405 | texCoord * 0.3 + timedWindDir * 0.008 + wavesNoise.w }; 406 | float height = 0; 407 | for (int i = 0; i < 4; ++i) 408 | { 409 | height += tex2Dlod(heightTexture, float4(texCoords[i], 0, 0)).w * wavesIntensity[i]; // was .x 410 | } 411 | 412 | return height; 413 | } 414 | 415 | float3 ComputeDisplacement(float3 worldPos, float cameraDistance, float2 noise, float timer, float4 waveSettings, float4 waveAmplitudes, float4 wavesIntensity, float4 waveNoise, 416 | out half3 normal, out half3 tangent) 417 | { 418 | float2 windDir = waveSettings.xy; 419 | float waveSteepness = waveSettings.z; 420 | float waveTiling = waveSettings.w; 421 | 422 | //TODO: improve motion/simulation instead of just noise 423 | //TODO: fix UV due to wave distortion 424 | 425 | wavesIntensity = normalize(wavesIntensity); 426 | waveNoise = half4(noise.x - noise.x * 0.2 + noise.y * 0.1, noise.x + noise.y * 0.5 - noise.y * 0.1, noise.x, noise.x) * waveNoise; 427 | half4 wavelengths = half4(1, 4, 3, 6) + waveNoise; 428 | half4 amplitudes = waveAmplitudes + half4(0.5, 1, 4, 1.5) * waveNoise; 429 | 430 | // reduce wave intensity base on distance to reduce aliasing 431 | wavesIntensity *= 1.0 - saturate(half4(cameraDistance / 120.0, cameraDistance / 150.0, cameraDistance / 170.0, cameraDistance / 400.0)); 432 | 433 | // compute position and normal from several sine and gerstner waves 434 | tangent = normal = half3(0, 1, 0); 435 | float2 timers = float2(timer * 0.5, timer * 0.25); 436 | for (int i = 2; i < 4; ++i) 437 | { 438 | float A = wavesIntensity[i] * amplitudes[i]; 439 | float3 vals = SineWaveValues(worldPos.xz * waveTiling, windDir, A, wavelengths[i], timer); 440 | normal += wavesIntensity[i] * SineWaveNormal(windDir, A, vals); 441 | tangent += wavesIntensity[i] * SineWaveTangent(windDir, A, vals); 442 | worldPos.y += SineWaveDelta(A, vals); 443 | } 444 | 445 | // using normalized wave steepness, tranform to Q 446 | float2 Q = waveSteepness / ((2 * 3.14159265 / wavelengths.xy) * amplitudes.xy); 447 | for (int j = 0; j < 2; ++j) 448 | { 449 | float A = wavesIntensity[j] * amplitudes[j]; 450 | float3 vals = GerstnerWaveValues(worldPos.xz * waveTiling, windDir, A, wavelengths[j], Q[j], timer); 451 | normal += wavesIntensity[j] * GerstnerWaveNormal(windDir, A, Q[j], vals); 452 | tangent += wavesIntensity[j] * GerstnerWaveTangent(windDir, A, Q[j], vals); 453 | worldPos += GerstnerWaveDelta(windDir, A, Q[j], vals); 454 | } 455 | 456 | normal = normalize(normal); 457 | tangent = normalize(tangent); 458 | if (length(wavesIntensity) < 0.01) 459 | { 460 | normal = half3(0, 1, 0); 461 | tangent = half3(0, 0, 1); 462 | } 463 | 464 | return worldPos; 465 | } 466 | #endif 467 | 468 | 469 | // 470 | // fresnel 471 | // 472 | 473 | half FresnelValue(float2 refractionValues, float3 normal, float3 eyeVec) 474 | { 475 | // R0 is a constant related to the index of refraction (IOR). 476 | float R0 = refractionValues.x; 477 | // This value modifies current fresnel term. If you want to weaken 478 | // reflections use bigger value. 479 | float refractionStrength = refractionValues.y; 480 | #ifdef SIMPLIFIED_FRESNEL 481 | return R0 + (1.0f - R0) * pow(1.0f - dot(eyeVec, normal), 5.0f); 482 | #else 483 | float angle = 1.0f - saturate(dot(normal, eyeVec)); 484 | float fresnel = angle * angle; 485 | fresnel *= fresnel; 486 | fresnel *= angle; 487 | return saturate(fresnel * (1.0f - saturate(R0)) + R0 - refractionStrength); 488 | #endif // #ifdef SIMPLIFIED_FRESNEL 489 | } 490 | 491 | // lightDir, eyeDir and normal in world space 492 | half3 ReflectedRadiance(float shininess, half3 specularValues, half3 lightColor, float3 lightDir, float3 eyeDir, float3 normal, float fresnel) 493 | { 494 | float shininessExp = specularValues.z; 495 | 496 | #ifdef BLINN_PHONG 497 | // a variant of the blinn phong shading 498 | float specularIntensity = specularValues.x * 0.0075; 499 | 500 | float3 H = normalize(eyeDir + lightDir); 501 | float e = shininess * shininessExp * 800; 502 | float kS = saturate(dot(normal, lightDir)); 503 | half3 specular = kS * specularIntensity * pow(saturate(dot(normal, H)), e) * sqrt((e + 1) / 2); 504 | specular *= lightColor; 505 | #else 506 | float2 specularIntensity = specularValues.xy; 507 | // reflect the eye vector such that the incident and emergent angles are equal 508 | float3 mirrorEye = reflect(-eyeDir, normal); 509 | half dotSpec = saturate(dot(mirrorEye, lightDir) * 0.5f + 0.5f); 510 | half3 specular = (1.0f - fresnel) * saturate(lightDir.y) * pow(dotSpec, specularIntensity.y) * (shininess * shininessExp + 0.2f) * lightColor; 511 | specular += specular * specularIntensity.x * saturate(shininess - 0.05f) * lightColor; 512 | #endif // #ifdef BLINN_PHONG 513 | return specular; 514 | } 515 | 516 | 517 | // 518 | // mean sky radiance 519 | // 520 | 521 | #ifdef USE_MEAN_SKY_RADIANCE 522 | 523 | // V, N, Tx, Ty in world space 524 | float2 U(float2 zeta, float3 V, float3 N, float3 Tx, float3 Ty) 525 | { 526 | float3 f = normalize(float3(-zeta, 1.0)); // tangent space 527 | float3 F = f.x * Tx + f.y * Ty + f.z * N; // world space 528 | float3 R = 2.0 * dot(F, V) * F - V; 529 | return dot(F, V); 530 | } 531 | 532 | // viewDir and normal in world space 533 | half3 MeanSkyRadiance(samplerCUBE skyTexture, float3 viewDir, half3 normal) 534 | { 535 | if (dot(viewDir, normal) < 0.0) 536 | { 537 | normal = reflect(normal, viewDir); 538 | } 539 | float3 ty = normalize(float3(0.0, normal.z, -normal.y)); 540 | float3 tx = cross(ty, normal); 541 | 542 | const float eps = 0.001; 543 | float2 u0 = U(float2(0, 0), viewDir, normal, tx, ty) * 0.05; 544 | float2 dux = 2.0 * (float2(eps, 0.0) - u0) / eps; 545 | float2 duy = 2.0 * (float2(0, eps) - u0) / eps; 546 | return texCUBE(skyTexture, float3(u0.xy, 1.0)).rgb; //TODO: transform hemispherical cordinates to cube or use a 2d texture 547 | } 548 | 549 | #endif // #ifdef USE_MEAN_SKY_RADIANCE 550 | 551 | 552 | // 553 | // bicubic filtering 554 | // 555 | 556 | float4 cubic(float v) 557 | { 558 | float4 n = float4(1.0, 2.0, 3.0, 4.0) - v; 559 | float4 s = n * n * n; 560 | float x = s.x; 561 | float y = s.y - 4.0 * s.x; 562 | float z = s.z - 4.0 * s.y + 6.0 * s.x; 563 | float w = 6.0 - x - y - z; 564 | return float4(x, y, z, w) * (1.0 / 6.0); 565 | } 566 | 567 | // 4 taps bicubic filtering, requires sampler to use bilinear filtering 568 | float4 tex2DBicubic(sampler2D tex, float texSize, float2 texCoords) 569 | { 570 | float2 texSize2 = texSize; 571 | float2 invTexSize = 1.0 / texSize2; 572 | 573 | texCoords = texCoords * texSize2 - 0.5; 574 | float2 fxy = frac(texCoords); 575 | texCoords -= fxy; 576 | 577 | float4 xcubic = cubic(fxy.x); 578 | float4 ycubic = cubic(fxy.y); 579 | 580 | float4 c = texCoords.xxyy + float2(-0.5, +1.5).xyxy; 581 | 582 | float4 s = float4(xcubic.xz + xcubic.yw, ycubic.xz + ycubic.yw); 583 | float4 offset = c + float4(xcubic.yw, ycubic.yw) / s; 584 | 585 | offset *= invTexSize.xxyy; 586 | 587 | float4 sample0 = tex2D(tex, offset.xz); 588 | float4 sample1 = tex2D(tex, offset.yz); 589 | float4 sample2 = tex2D(tex, offset.xw); 590 | float4 sample3 = tex2D(tex, offset.yw); 591 | 592 | float sx = s.x / (s.x + s.y); 593 | float sy = s.z / (s.z + s.w); 594 | 595 | return lerp(lerp(sample3, sample2, sx), lerp(sample1, sample0, sx), sy); 596 | } 597 | 598 | 599 | 600 | // 601 | // foam 602 | // 603 | 604 | half FoamColor(sampler2D tex, float2 texCoord, float2 texCoord2, float2 ranges, half2 factors, float waterDepth, half baseColor) 605 | { 606 | float f1 = tex2D(tex, texCoord).r; 607 | float f2 = tex2D(tex, texCoord2).r; 608 | return lerp(f1 * factors.x + f2 * factors.y, baseColor, smoothstep(ranges.x, ranges.y, waterDepth)); 609 | } 610 | 611 | // surfacePosition, depthPosition, eyeVec in world space 612 | // waterDepth is the horizontal water depth in world space 613 | half FoamValue(sampler2D shoreTexture, sampler2D foamTexture, float2 foamTiling, 614 | float4 foamNoise, float2 foamSpeed, float3 foamRanges, float maxAmplitude, 615 | float3 surfacePosition, float3 depthPosition, float3 eyeVec, float waterDepth, 616 | float2 timedWindDir, float timer) 617 | { 618 | float2 position = (surfacePosition.xz + eyeVec.xz * 0.1) * 0.5; 619 | 620 | float s = sin(timer * 0.01 + depthPosition.x); 621 | float2 texCoord = position + timer * 0.01 * foamSpeed + s * 0.05; 622 | s = sin(timer * 0.01 + depthPosition.z); 623 | float2 texCoord2 = (position + timer * 0.015 * foamSpeed + s * 0.05) * -0.5; // also flip 624 | float2 texCoord3 = texCoord * foamTiling.x; 625 | float2 texCoord4 = (position + timer * 0.015 * -foamSpeed * 0.3 + s * 0.05) * -0.5 * foamTiling.x; // reverse direction 626 | texCoord *= foamTiling.y; 627 | texCoord2 *= foamTiling.y; 628 | 629 | float2 ranges = foamRanges.xy; 630 | ranges.x += snoise(surfacePosition.xz + foamNoise.z * timedWindDir) * foamNoise.x; 631 | ranges.y += snoise(surfacePosition.xz + foamNoise.w * timedWindDir) * foamNoise.y; 632 | ranges = clamp(ranges, 0.0, 10.0); 633 | 634 | float foamEdge = max(ranges.x, ranges.y); 635 | half deepFoam = FoamColor(foamTexture, texCoord, texCoord2, float2(ranges.x, foamEdge), half2(1.0, 0.5), waterDepth, 0.0); 636 | half foam = 0;//= FoamColor(shoreTexture, texCoord3 * 0.25, texCoord4, float2(0.0, ranges.x), half2(0.75, 1.5), waterDepth, deepFoam); 637 | 638 | // high waves foam 639 | //if (surfacePosition.y - foamRanges.z > 0.0001f) 640 | { 641 | half amount = saturate((surfacePosition.y - foamRanges.z) / maxAmplitude) * 0.25; 642 | foam += (tex2D(shoreTexture, texCoord3).x + tex2D(shoreTexture, texCoord4).x * 0.5f) * amount; 643 | } 644 | 645 | return foam; 646 | } 647 | 648 | // surfacePosition, depthPosition, eyeVec in world space 649 | // waterDepth is the horizontal water depth in world space 650 | half FoamValueAlphaShore(sampler2D shoreTexture, sampler2D foamTexture , float2 foamTiling, 651 | float4 foamNoise , float2 foamSpeed , float3 foamRanges, 652 | float maxAmplitude, float3 surfacePosition , float3 depthPosition, 653 | float3 eyeVec , float waterDepth , float2 timedWindDir, 654 | float timer) 655 | { 656 | float2 position = (surfacePosition.xz + eyeVec.xz * 0.1) * 0.5; 657 | 658 | float s = sin(timer * 0.01 + depthPosition.x); 659 | float2 texCoord = position + timer * 0.01 * foamSpeed + s * 0.05; 660 | s = sin(timer * 0.01 + depthPosition.z); 661 | float2 texCoord2 = (position + timer * 0.015 * foamSpeed + s * 0.05) * -0.5; // also flip 662 | float2 texCoord3 = texCoord * foamTiling.x; 663 | float2 texCoord4 = (position + timer * 0.015 * -foamSpeed * 0.3 + s * 0.05) * -0.5 * foamTiling.x; // reverse direction 664 | 665 | texCoord *= foamTiling.y; 666 | texCoord2 *= foamTiling.y; 667 | 668 | float2 ranges = foamRanges.xy; 669 | ranges.x += snoise(surfacePosition.xz + (foamNoise.z) * timedWindDir) * foamNoise.x; 670 | ranges.y += snoise(surfacePosition.xz + foamNoise.w * timedWindDir) * foamNoise.y; 671 | ranges = clamp(ranges, 0.0, 10.0); 672 | 673 | float foamEdge = max(ranges.x, ranges.y); 674 | half foam = FoamColor(foamTexture, texCoord, texCoord2, float2(ranges.x, foamEdge), half2(1.0, 4.5), waterDepth, 0);//-2.0); 675 | //half foam = FoamColor(shoreTexture, texCoord3 * 0.25, texCoord4, float2(0.0, ranges.x), half2(0.75, 1.5), 1.2, deepFoam); 676 | 677 | return foam; 678 | } -------------------------------------------------------------------------------- /raw/shader_bin/shader_src/lib/transform.hlsl: -------------------------------------------------------------------------------- 1 | float4 Transform_ObjectToWorld( float4 objectSpacePosition ) 2 | { 3 | return mul( objectSpacePosition, worldMatrix ); 4 | } 5 | 6 | 7 | float4 Transform_ObjectToView( float4 objectSpacePosition ) 8 | { 9 | return mul( objectSpacePosition, worldViewMatrix ); 10 | } 11 | 12 | 13 | float4 Transform_ObjectToClip( float4 objectSpacePosition ) 14 | { 15 | return mul( objectSpacePosition, worldViewProjectionMatrix ); 16 | } 17 | 18 | 19 | float4 Transform_WorldToView( float4 worldSpacePosition ) 20 | { 21 | return mul( worldSpacePosition, viewMatrix ); 22 | } 23 | 24 | 25 | float4 Transform_WorldToClip( float4 worldSpacePosition ) 26 | { 27 | return mul( worldSpacePosition, viewProjectionMatrix ); 28 | } 29 | 30 | 31 | float4 Transform_ViewToClip( float4 viewSpacePosition ) 32 | { 33 | return mul( viewSpacePosition, projectionMatrix ); 34 | } 35 | 36 | 37 | float3 Transform_Dir_ObjectToWorld( float3 objectSpaceDir ) 38 | { 39 | return mul( objectSpaceDir, inverseTransposeWorldMatrix ); 40 | } 41 | 42 | 43 | float3 Transform_Dir_ObjectToView( float3 objectSpaceDir ) 44 | { 45 | return mul( objectSpaceDir, inverseTransposeWorldViewMatrix ); 46 | } 47 | 48 | 49 | float3 Transform_Dir_ObjectToClip( float3 objectSpaceDir ) 50 | { 51 | return mul( objectSpaceDir, inverseTransposeWorldViewProjectionMatrix ); 52 | } 53 | 54 | 55 | float3 Transform_Dir_WorldToView( float3 worldSpaceDir ) 56 | { 57 | return mul( worldSpaceDir, inverseTransposeViewMatrix ); 58 | } 59 | 60 | 61 | float3 Transform_Dir_WorldToClip( float3 worldSpaceDir ) 62 | { 63 | return mul( worldSpaceDir, inverseTransposeViewProjectionMatrix ); 64 | } 65 | 66 | 67 | float3 Transform_Dir_ViewToClip( float3 viewSpaceDir ) 68 | { 69 | return mul( viewSpaceDir, inverseTransposeProjectionMatrix ); 70 | } 71 | 72 | 73 | float3 Transform_Normal_WorldToTangent( const float3x3 tangentSpaceMatrix, const float3 worldDirection ) 74 | { 75 | float3x3 worldDirToLocalDir; 76 | float3 localDirection; 77 | 78 | worldDirToLocalDir = transpose( mul( tangentSpaceMatrix, worldMatrix ) ); 79 | localDirection = mul( worldDirection, worldDirToLocalDir ); 80 | return localDirection; 81 | } 82 | 83 | // get screen texcoords for worldViewProjected vertices 84 | float4 Transform_ClipSpacePosToTexCoords( float4 position ) 85 | { 86 | return position * clipSpaceLookupScale + position.w * clipSpaceLookupOffset; 87 | } 88 | -------------------------------------------------------------------------------- /raw/shader_bin/shader_src/lib/utility.hlsl: -------------------------------------------------------------------------------- 1 | float toRange( float originalStart, float originalEnd, // original range 2 | float newStart, float newEnd, // desired range 3 | float value) // value to convert 4 | { 5 | float originalDiff = originalEnd - originalStart; 6 | float newDiff = newEnd - newStart; 7 | float ratio = newDiff / originalDiff; 8 | float newProduct = value * ratio; 9 | float finalValue = newProduct + newStart; 10 | return finalValue; 11 | } 12 | 13 | float toRange2( float OLD_MIN, float OLD_MAX, // original range 14 | float NEW_MIN, float NEW_MAX, // desired range 15 | float value) // value to convert 16 | { 17 | float old_range = (value - OLD_MIN) / (OLD_MAX - OLD_MIN); 18 | return ((NEW_MAX - NEW_MIN) * old_range) + NEW_MIN; 19 | } 20 | 21 | // returns the 2D distance from camera to a position in worldSpace 22 | float get_camera_distance_to_pos2d(float2 position_xy) 23 | { 24 | return distance(inverseWorldMatrix[3].xy, position_xy); 25 | } 26 | 27 | // returns the 3D distance from camera to a position in worldSpace 28 | float get_camera_distance_to_pos3d(float3 position_xyz) 29 | { 30 | return distance(inverseWorldMatrix[3].xyz, position_xyz); 31 | } 32 | 33 | // returns 1 if facing forward, 0 if facing up/down 34 | float get_camera_angle_vertical() 35 | { 36 | return viewMatrix[2].y; 37 | } 38 | 39 | float4x4 rotation_matrix_4x4(float3 axis, float4 d) 40 | { 41 | float cx, cy, cz, sx, sy, sz; 42 | 43 | sincos(axis.x, sx, cx); 44 | sincos(axis.y, sy, cy); 45 | sincos(axis.z, sz, cz); 46 | 47 | return float4x4( cy*cz, -sz, sy, d.x, 48 | sz, cx*cz, -sx, d.y, 49 | -sy, sx, cx*cy, d.z, 50 | 0, 0, 0, d.w ); 51 | } 52 | 53 | // 54 | // tangent 55 | // 56 | 57 | // input :: (float4) vertex.tangent 58 | float3 setup_tangent(float4 vertex_tangent) 59 | { 60 | return (vertex_tangent.zxy * 0.00787401572 - 1.0) * (vertex_tangent.w * 0.00392156886 + 0.752941191); 61 | } 62 | 63 | // transforms vertex tangent to clipspace (uses world/view/projection matrices) 64 | float4 transform_tangent_clipspace_wvp(float3 setup_tangent) 65 | { 66 | float4 tan_proj; 67 | 68 | tan_proj = mul(setup_tangent.yzx, worldMatrix); 69 | tan_proj = mul(tan_proj, viewMatrix); 70 | tan_proj = mul(tan_proj, projectionMatrix); 71 | 72 | return float4(1, -1, 1, 1) * clipSpaceLookupScale * tan_proj; 73 | } 74 | 75 | // transforms vertex tangent to clipspace (uses worldViewProjection matrix) 76 | float4 transform_tangent_clipspace(float3 setup_tangent) 77 | { 78 | float4 tan_proj = mul(setup_tangent.yzx, worldViewProjectionMatrix); 79 | 80 | return float4(1, -1, 1, 1) * clipSpaceLookupScale * tan_proj; 81 | } 82 | 83 | // 84 | // binormal 85 | // 86 | 87 | // returns the binormal :: input :: (float4) vertex.normal 88 | float3 setup_binormal(float4 vertex_normal) 89 | { 90 | return (vertex_normal.yzx * 0.00787401572 - 1.0) * (vertex_normal.w * 0.00392156886 + 0.752941191); 91 | } 92 | 93 | // transforms binormal to clipspace (uses world/view/projection matrices) 94 | float4 transform_binormal_clipspace_wvp(float3 setup_tangent, float3 setup_binormal) 95 | { 96 | float4 binormal_proj; 97 | 98 | binormal_proj = mul(setup_tangent.zxy * setup_binormal.yzx - (setup_tangent * setup_binormal), worldMatrix); 99 | binormal_proj = mul(binormal_proj, viewMatrix); 100 | binormal_proj = mul(binormal_proj, projectionMatrix); 101 | 102 | return float4(-1, 1, -1, -1) * clipSpaceLookupScale * binormal_proj; 103 | } 104 | 105 | // transforms binormal to clipspace (uses worldViewProjection matrix) 106 | float4 transform_binormal_clipspace(float3 setup_tangent, float3 setup_binormal) 107 | { 108 | float4 binormal_proj = mul(setup_tangent.zxy * setup_binormal.yzx - (setup_tangent * setup_binormal), worldViewProjectionMatrix); 109 | 110 | return float4(-1, 1, -1, -1) * clipSpaceLookupScale * binormal_proj; 111 | } -------------------------------------------------------------------------------- /raw/shader_bin/shader_src/ps_3_0_worldfx_ocean.hlsl: -------------------------------------------------------------------------------- 1 | // * xoxor4d.github.io 2 | // * original shader : https://github.com/tuxalin/water-shader 3 | 4 | #define PC 5 | #define IS_VERTEX_SHADER 0 6 | #define IS_PIXEL_SHADER 1 7 | 8 | // use custom code constants (iw3xo-devgui) 9 | #define USE_CUSTOM_CONSTANTS 10 | 11 | //#define REVERSED_Z // reversed depth 12 | #define USE_DISPLACEMENT 13 | #define USE_FOAM 14 | #define USE_SHORE_FOAM 15 | #define USE_MEAN_SKY_RADIANCE // can be used for any sort of cubemap (eg. a "custom" reflection probe) 16 | //#define USE_REFLECTION_PROBES // uses the ^ cubemap otherwise (only if USE_MEAN_SKY_RADIANCE is defined) 17 | 18 | //#define DEBUG_NORMALS 19 | //#define DEBUG_WATERDEPTH 20 | //#define DEBUG_PURE_REFRECTION 21 | //#define DEBUG_SHORE_FADE 22 | //#define DEBUG_POSITION_FROM_DEPTH 23 | 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | struct PixelInput 31 | { 32 | float4 position : POSITION; 33 | float4 color : COLOR; 34 | float3 normal : NORMAL; 35 | float3 uv : TEXCOORD0; 36 | float3 tangent : TEXCOORD1; 37 | float3 bitangent : TEXCOORD2; 38 | float3 worldPos : TEXCOORD3; 39 | float4 projPos : TEXCOORD4; 40 | float4 camPosInvDist: TEXCOORD5; 41 | float3 camPos : TEXCOORD6; 42 | float2 wind : TEXCOORD7; 43 | }; 44 | 45 | struct PixelOutput 46 | { 47 | float4 color : COLOR; 48 | }; 49 | 50 | static float2 rcpres = float2(texelSizeX, texelSizeY); // size of 1 pixel horz. and vert. 51 | static float FOV = 80; 52 | static const float2 g_InvFocalLen = { tan(0.5f * radians(FOV)) / rcpres.y * rcpres.x, tan(0.5f * radians(FOV)) }; 53 | 54 | float3 fetch_eye_pos(float2 uv, float eye_z) 55 | { 56 | uv = (uv * float2(-2.0, 2.0) - float2(-1.0, 1.0)); 57 | #ifdef REVERSED_Z 58 | eye_z = 1.0f - eye_z; 59 | #endif 60 | 61 | return float3(uv * g_InvFocalLen * eye_z, eye_z); 62 | } 63 | 64 | // dx9 : VFACE : Floating-point scalar that indicates a back-facing primitive. A negative value faces backwards, while a positive value faces the camera. 65 | // dx9 : VPOS : screen coords of current pixel 66 | 67 | PixelOutput ps_main( const PixelInput pixel) 68 | { 69 | PixelOutput fragment; 70 | 71 | #ifdef USE_CUSTOM_CONSTANTS 72 | 73 | // both vs / ps 74 | float4 _WaveAmplitude = float4(1 * filterTap[0]); 75 | float4 _WavesIntensity = float4(1 * filterTap[1]); 76 | float4 _WavesNoise = float4(1 * filterTap[2]); 77 | 78 | // colors 79 | float3 _AmbientColor = float3(1 * filterTap[3].xyz); 80 | float _AmbientDensity = 1 * filterTap[3].w; 81 | 82 | float3 _ShoreColor = float3(1 * filterTap[4].xyz); 83 | float _DiffuseDensity = 1 * filterTap[4].w; 84 | 85 | float3 _SurfaceColor = float3(1 * filterTap[5].xyz); 86 | float _NormalIntensity = 1 * filterTap[5].w; 87 | 88 | float3 _DepthColor = float3(1 * filterTap[6].xyz); 89 | float _ShoreFade = 1 * filterTap[6].w; 90 | 91 | // refraction 92 | float3 _RefractionValues = float3(1 * filterTap[7].xyz); 93 | float _RefractionScale = 1 * filterTap[7].w; 94 | 95 | float3 _HorizontalExtinction = float3(1 * colorMatrixR.xyz); 96 | float _Distortion = 1 * colorMatrixR.w; 97 | 98 | float _WaterClarity = 1 * colorMatrixG.x; 99 | float _WaterTransparency = 1 * colorMatrixG.y; 100 | float _RadianceFactor = 1 * colorMatrixG.z; // 1 float left empty 101 | 102 | // spec 103 | float3 _SpecularValues = float3(1 * colorMatrixB.xyz); 104 | float _Shininess = 1 * colorMatrixB.w; 105 | 106 | // shore/foam 107 | float3 _FoamTiling = float3(1 * dofEquationViewModelAndFarBlur.xyz); 108 | float _FoamSpeed = 1 * dofEquationViewModelAndFarBlur.w; 109 | 110 | float3 _FoamRanges = float3(1 * dofEquationScene.xyz); 111 | float _FoamIntensity = 1 * dofEquationScene.w; 112 | 113 | float4 _FoamNoise = float4(1 * dofLerpScale); // y: inner blend z: inner blend to outer dist //float4(0.1, 0.12, 0.1, 0.2); 114 | 115 | #else // ------------------------------------------ 116 | 117 | // both vs / ps 118 | const float4 _WaveAmplitude = float4(0.72, 0.4, 0.46, 1.93); 119 | float4 _WavesIntensity = float4(0.28, 1.95, 1, 1.9); 120 | float4 _WavesNoise = float4(0.05, 0.45, 1.18, 0.28); 121 | 122 | // colors 123 | const float3 _AmbientColor = float3(1, 1, 1); 124 | const float _AmbientDensity = -0.0075; 125 | const float3 _ShoreColor = float3(1, 1, 1); 126 | const float _DiffuseDensity = -0.2649; 127 | const float3 _SurfaceColor = float3(0.871, 0.953, 0.804); 128 | const float _NormalIntensity = 0.9549; 129 | const float3 _DepthColor = float3(0.914, 0.988, 1.047); 130 | const float _ShoreFade = 0.0073; 131 | 132 | // refraction 133 | const float3 _RefractionValues = float3(-0.2637, 0.4148, 1); 134 | const float _RefractionScale = 0.005; 135 | const float3 _HorizontalExtinction = float3(100, 250, 500); 136 | const float _Distortion = 0.4; 137 | const float _WaterClarity = 12; 138 | const float _WaterTransparency = 500; 139 | const float _RadianceFactor = -1.75; 140 | 141 | // spec 142 | const float3 _SpecularValues = float3(17.75, 43, 5.5); 143 | const float _Shininess = 0.68; 144 | 145 | // shore/foam 146 | const float3 _FoamTiling = float3(0.075, 0.25, -0.7); 147 | const float _FoamSpeed = 150; 148 | const float3 _FoamRanges = float3(1.8, 2.2, 2.46); 149 | float _FoamIntensity = 14; 150 | const float4 _FoamNoise = float4(1, 1, 1, 1); 151 | 152 | #endif // USE_CUSTOM_CONSTANTS 153 | 154 | // -------------------------------------------------------- 155 | 156 | float4 _WorldSpaceCameraPos = float4(pixel.camPos.xyz, 1.0); 157 | 158 | float timer = pixel.uv.z; 159 | float2 windDir = pixel.wind.xy; 160 | float2 timedWindDir = pixel.wind.xy * timer; 161 | float2 ndcPos = float2(pixel.projPos.xy / pixel.projPos.w); 162 | float3 eyeDir = normalize(_WorldSpaceCameraPos.xzy - float3(pixel.worldPos.x, pixel.worldPos.y + 10000, pixel.worldPos.z)); // hack, "worldPos" is still in local space, so we are working with the model origin resulting in odd behaviour 163 | float3 eyeDirWorld = normalize(pixel.camPosInvDist); 164 | 165 | float3 surfacePosition = pixel.worldPos; 166 | half3 lightColor = sunDiffuse.rgb; 167 | 168 | // compensate _FoamIntensity by the amount of sunlight so we dont need to tweak the shader everytime we increase/decrease the maps sunlight 169 | _FoamIntensity = _FoamIntensity / (((sunDiffuse.r + sunDiffuse.g + sunDiffuse.b) * 0.333f) * 1.5f + 0.5); 170 | 171 | //wave normal 172 | half3 normal = ComputeNormal(normalMapSampler, surfacePosition.xz, pixel.uv, pixel.normal, pixel.tangent, pixel.bitangent, _WavesNoise, _WavesIntensity, timedWindDir); 173 | normal = normalize(lerp(pixel.normal, normalize(normal), _NormalIntensity)); 174 | 175 | //not propper 176 | float3 depthPosition = fetch_eye_pos(ndcPos, 1); 177 | depthPosition = depthPosition.xzy; 178 | depthPosition.y = surfacePosition.y - 100; // hack 179 | 180 | //not propper 181 | float waterDepth, viewWaterDepth, waterDepthDbg; 182 | 183 | waterDepth = tex2D(floatZSampler, ndcPos).r; 184 | waterDepth -= pixel.projPos.w; 185 | waterDepth /= 2; 186 | viewWaterDepth = waterDepth; // meh 187 | waterDepthDbg = waterDepth; 188 | 189 | // refraction 190 | float2 dudv = float2(ndcPos.x, ndcPos.y * 0.98); 191 | { 192 | // refraction based on water depth 193 | float refractionScale = _RefractionScale * min(waterDepth, 1.0f); 194 | 195 | float2 delta = float2(sin(timer + 3.0f * abs(1/waterDepth)), 196 | sin(timer + 5.0f * abs(1/waterDepth))); 197 | 198 | dudv = dudv + windDir * delta * refractionScale; 199 | } 200 | 201 | half3 pureRefractionColor = tex2D(colorMapPostSunSampler, dudv).rgb; // half3(1,0,0); // _RefractionTexture 202 | 203 | float2 waterTransparency = float2(_WaterClarity, _WaterTransparency); 204 | float2 waterDepthValues = float2(waterDepth, viewWaterDepth); 205 | float shoreRange = max(_FoamRanges.x, _FoamRanges.y) * 2.0; 206 | half3 refractionColor = DepthRefraction(waterTransparency, waterDepthValues, shoreRange, _HorizontalExtinction, pureRefractionColor, _ShoreColor, _SurfaceColor, _DepthColor); 207 | 208 | // compute light's reflected radiance 209 | float3 lightDir = normalize(sunPosition.xzy); 210 | half fresnel = FresnelValue(_RefractionValues, normal, eyeDir); 211 | half3 specularColor = ReflectedRadiance(_Shininess, _SpecularValues, lightColor, lightDir, eyeDirWorld, normal, fresnel); 212 | 213 | 214 | // ----------------------- 215 | // compute reflected color 216 | 217 | #ifdef USE_MEAN_SKY_RADIANCE // compute sky's reflected radiance 218 | half3 reflectColor = fresnel * MeanSkyRadiance(skyMapSampler, eyeDirWorld, normal) * _RadianceFactor; 219 | #else 220 | half3 reflectColor = 0; 221 | #endif // #ifdef USE_MEAN_SKY_RADIANCE 222 | 223 | 224 | dudv = ndcPos + _Distortion * normal.xz; 225 | 226 | 227 | #ifdef USE_REFLECTION_PROBES // # using reflectionprobes 228 | 229 | float3 reflectVec = normalize(reflect(pixel.camPosInvDist.xyz, normal.xzy * _Distortion)); 230 | reflectColor += texCUBE(reflectionProbeSampler, reflectVec); 231 | 232 | #else // # user defined cubemap for reflection (a sky in this case) 233 | #ifdef USE_MEAN_SKY_RADIANCE 234 | 235 | float3 reflectVec = normalize(reflect(eyeDirWorld, normal.xzy * _Distortion)); // normalize(reflect(pixel.camPosInvDist.yxz, normal.xzy * _Distortion)); 236 | 237 | // rotate reflection vector by 180 deg 238 | float4x4 rot_mat = rotation_matrix_4x4(float3(0.0, 0.0, M_PI), float4(0.0, 0.0, 0.0, 1.0)); 239 | reflectVec = mul(reflectVec, rot_mat); 240 | 241 | reflectColor += texCUBE(skyMapSampler, reflectVec); 242 | 243 | #endif 244 | #endif // #ifdef USE_REFLECTION_PROBES 245 | 246 | 247 | // ----------------------- 248 | // wave foam 249 | 250 | float maxAmplitude = max(max(_WaveAmplitude.x, _WaveAmplitude.y), _WaveAmplitude.z); 251 | 252 | #ifdef USE_FOAM 253 | 254 | //_ShoreTexture (rgb) _FoamTexture (rgb) (modified FoamValue function, doesnt use colorMapSampler anymore) 255 | half foam = FoamValue(specularMapSampler, colorMapSampler, _FoamTiling, _FoamNoise, _FoamSpeed * windDir, _FoamRanges, maxAmplitude, surfacePosition, depthPosition, eyeDir, waterDepth, timedWindDir, timer); 256 | foam = foam * _FoamIntensity; 257 | 258 | #else 259 | half foam = 0; 260 | #endif // #ifdef USE_FOAM 261 | 262 | 263 | // ---------------------- 264 | 265 | half shoreFade = saturate(waterDepth * _ShoreFade); 266 | 267 | // ambient + diffuse 268 | half3 ambientColor = _AmbientColor.rgb * _AmbientDensity + saturate(dot(normal, lightDir)) * _DiffuseDensity; 269 | 270 | // refraction color with depth based color 271 | pureRefractionColor = lerp(pureRefractionColor, reflectColor, fresnel * saturate(waterDepth / (_FoamRanges.x * 0.4))); 272 | pureRefractionColor = lerp(pureRefractionColor, _ShoreColor, 0.30 * shoreFade); 273 | 274 | // compute final color 275 | half3 color = lerp(refractionColor, reflectColor, fresnel); 276 | color = saturate(ambientColor + color + max(specularColor, foam * lightColor)); 277 | color = lerp(pureRefractionColor + specularColor * shoreFade, color, shoreFade); 278 | 279 | 280 | // ----------------------- 281 | // shore foam 282 | 283 | #ifdef USE_SHORE_FOAM 284 | 285 | timer *= 0.25; // reduce shore foam scroll 286 | half alphaFoam = FoamValueAlphaShore(specularMapSampler, specularMapSampler, _FoamTiling, _FoamNoise, _FoamSpeed * windDir, _FoamRanges, maxAmplitude, surfacePosition, depthPosition, eyeDirWorld, waterDepth * 0.25, timedWindDir, timer); 287 | 288 | float dist_cam_to_vert = pixel.camPosInvDist.w; 289 | float sprinkle_scalar = clamp(toRange2(0, 450, 1, 0, dist_cam_to_vert), 0, 1); 290 | 291 | // fade out shore foam 292 | if(dist_cam_to_vert >= 0 && dist_cam_to_vert < 450) 293 | { 294 | alphaFoam = (alphaFoam * sprinkle_scalar) * _FoamIntensity * 0.0075; 295 | color += (alphaFoam); 296 | } 297 | 298 | #endif // #ifdef USE_SHORE_FOAM 299 | 300 | 301 | // ----------------------- 302 | // final color 303 | 304 | fragment.color.rgb = color.rgb; 305 | 306 | // fade out water towards shore depending on waterDepth 307 | waterDepth = clamp(waterDepth * 0.15, 0, 1); 308 | fragment.color.a = pixel.color.a * (waterDepth); 309 | 310 | 311 | // ----------------------- 312 | // debug stuff 313 | 314 | #ifdef DEBUG_NORMALS 315 | color.rgb = 0.5 + 2 * ambientColor + specularColor + clamp(dot(normal, lightDir), 0, 1) * 0.5; 316 | fragment.color.rgb = color.rgb + (fragment.color.rgb * 0.0001); 317 | #endif 318 | 319 | #ifdef DEBUG_WATERDEPTH 320 | color.rgb = float3(waterDepthDbg / 100, 0, 0); 321 | fragment.color.rgb = color.rgb + (fragment.color.rgb * 0.0001); 322 | #endif 323 | 324 | #ifdef DEBUG_PURE_REFRECTION 325 | color.rgb = float3(pureRefractionColor); 326 | fragment.color.rgb = color.rgb + (fragment.color.rgb * 0.0001); 327 | #endif 328 | 329 | #ifdef DEBUG_POSITION_FROM_DEPTH 330 | color.rgb = float3(depthPosition.xzy); 331 | fragment.color.rgb = color.rgb + (fragment.color.rgb * 0.0001); 332 | #endif 333 | 334 | #ifdef DEBUG_SHORE_FADE 335 | color.rgb = float3(shoreFade, shoreFade, shoreFade); 336 | fragment.color.rgb = color.rgb + (fragment.color.rgb * 0.0001); 337 | #endif 338 | 339 | return fragment; 340 | } 341 | -------------------------------------------------------------------------------- /raw/shader_bin/shader_src/ps_3_0_worldfx_ocean_unlit.hlsl: -------------------------------------------------------------------------------- 1 | #define PC 2 | #define IS_VERTEX_SHADER 0 3 | #define IS_PIXEL_SHADER 1 4 | 5 | // no support for custom code constants when using fullbright 6 | //#define USE_CUSTOM_CONSTANTS 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | struct PixelInput 13 | { 14 | float4 position : POSITION; 15 | float3 normal : NORMAL; 16 | float3 uv : TEXCOORD0; 17 | float3 tangent : TEXCOORD1; 18 | float3 bitangent : TEXCOORD2; 19 | float3 worldPos : TEXCOORD3; 20 | float2 wind : TEXCOORD4; 21 | }; 22 | 23 | float4 ps_main( const PixelInput pixel ) : COLOR 24 | { 25 | // both vs / ps 26 | const float4 _WaveAmplitude = float4(0.72, 0.4, 0.46, 1.93); 27 | float4 _WavesIntensity = float4(0.28, 1.95, 1, 1.9); 28 | float4 _WavesNoise = float4(0.05, 0.45, 1.18, 0.28); 29 | 30 | const float _NormalIntensity = 0.9549; 31 | const float _Distortion = 0.4; 32 | 33 | float timer = pixel.uv.z; 34 | float2 timedWindDir = pixel.wind.xy * timer; 35 | float3 surfacePosition = pixel.worldPos; 36 | 37 | //wave normal 38 | half3 normal = ComputeNormal(normalMapSampler, surfacePosition.xz, pixel.uv, pixel.normal, pixel.tangent, pixel.bitangent, _WavesNoise, _WavesIntensity, timedWindDir); 39 | normal = normalize(lerp(pixel.normal, normalize(normal), _NormalIntensity)); 40 | 41 | // rotate reflection vector by 180 deg 42 | float3 reflectVec = normalize(reflect(pixel.worldPos.xyz, normal.xzy * _Distortion)); 43 | 44 | float4x4 rot_mat = rotation_matrix_4x4(float3(0.0, 0.0, M_PI), float4(0.0, 0.0, 0.0, 1.0)); 45 | reflectVec = mul(reflectVec, rot_mat); 46 | 47 | return float4(texCUBE(skyMapSampler, reflectVec).rgb, 1.0f); 48 | } 49 | -------------------------------------------------------------------------------- /raw/shader_bin/shader_src/shader_vars.h: -------------------------------------------------------------------------------- 1 | #if defined( IS_PIXEL_SHADER ) && IS_PIXEL_SHADER 2 | #define PIXEL_REGISTER( index ) : register( index ) 3 | #else 4 | #define PIXEL_REGISTER( index ) 5 | #endif 6 | 7 | #if defined( IS_VERTEX_SHADER ) && IS_VERTEX_SHADER 8 | #define VERTEX_REGISTER( index ) : register( index ) 9 | #else 10 | #define VERTEX_REGISTER( index ) 11 | #endif 12 | 13 | #define SAMPLER_REGISTER( index ) : register( index ) 14 | 15 | #ifndef PS3 16 | #define PS3_SAMPLER_REGISTER( index ) 17 | #else 18 | #define PS3_SAMPLER_REGISTER( index ) : register( index ) 19 | #endif 20 | 21 | #ifdef CG 22 | #define UNROLL 23 | #else 24 | #define UNROLL [unroll] 25 | #endif 26 | 27 | #define LIGHT_NONE 0 28 | #define LIGHT_SUN 1 29 | #define LIGHT_SPOT 2 30 | #define LIGHT_OMNI 3 31 | 32 | #define VERTDECL_DEFAULT 0 33 | #define VERTDECL_SIMPLE 1 34 | 35 | #define FLOATZ_CLEAR_THRESHOLD 1.5e6 36 | #define FLOATZ_CLEAR_DEPTH 2.0e6 37 | 38 | 39 | #define SIZECONST_WIDTH 0 40 | #define SIZECONST_HEIGHT 1 41 | #define SIZECONST_INV_WIDTH 2 42 | #define SIZECONST_INV_HEIGHT 3 43 | 44 | #define SPOTLIGHT_DOT_SCALE 0 45 | #define SPOTLIGHT_DOT_BIAS 1 46 | #define SPOTLIGHT_EXPONENT 2 47 | #define SPOTLIGHT_SHADOW_FADE 3 48 | 49 | #define M_PI 3.14159265358979323846 50 | 51 | #define vec2 float2 52 | #define vec3 float3 53 | #define vec4 float4 54 | #define mat2 float2x2 55 | #define mat3 float3x3 56 | #define mix lerp 57 | #define mod fmod 58 | #define fract frac 59 | 60 | ///////////////////////////////////////////////////// 61 | // MATRICES ( registers can be changed to fit needs ) 62 | 63 | float4x4 worldMatrix VERTEX_REGISTER( c4 ); // from object space to world space 64 | //float4x4 inverseWorldMatrix; 65 | float4x4 inverseWorldMatrix VERTEX_REGISTER( c24 ); // camera pos in world space ( output.cameraPos = inverseWorldMatrix[3]; ) // mostly for models 66 | float4x4 transposeWorldMatrix; 67 | float4x4 inverseTransposeWorldMatrix; 68 | 69 | float4x4 projectionMatrix VERTEX_REGISTER( c0 ); // was c8 70 | float4x4 inverseProjectionMatrix; //VERTEX_REGISTER( c8 ); 71 | float4x4 transposeProjectionMatrix; 72 | float4x4 inverseTransposeProjectionMatrix; 73 | 74 | 75 | float4x4 worldViewProjectionMatrix VERTEX_REGISTER( c0 ); 76 | float4x4 inverseWorldViewProjectionMatrix; 77 | float4x4 transposeWorldViewProjectionMatrix; 78 | float4x4 inverseTransposeWorldViewProjectionMatrix; 79 | 80 | 81 | float4x4 viewMatrix VERTEX_REGISTER( c8 ); // had no register ([2].y cam up/down || up = 0.09, forward = 1, down = 0.09) 82 | float4x4 inverseViewMatrix VERTEX_REGISTER( c28 ); // EYEPOS = _m30, _m31, _m32, (_m33) || inverseViewMatrix[3] // camera pos for world objects 83 | float4x4 transposeViewMatrix; 84 | float4x4 inverseTransposeViewMatrix; 85 | 86 | 87 | float4x4 viewProjectionMatrix VERTEX_REGISTER( c0 ); 88 | float4x4 inverseViewProjectionMatrix VERTEX_REGISTER( c4 ); 89 | float4x4 transposeViewProjectionMatrix; 90 | float4x4 inverseTransposeViewProjectionMatrix; 91 | 92 | 93 | float4x4 worldViewMatrix VERTEX_REGISTER( c4 ); 94 | float4x4 inverseWorldViewMatrix VERTEX_REGISTER( c28 ); 95 | float4x4 transposeWorldViewMatrix; 96 | float4x4 inverseTransposeWorldViewMatrix VERTEX_REGISTER( c8 ); // used to transform the vertex normal from object space to world space 97 | 98 | 99 | float4x4 shadowLookupMatrix VERTEX_REGISTER( c24 ); 100 | float4x4 inverseShadowLookupMatrix; 101 | float4x4 transposeShadowLookupMatrix; 102 | float4x4 inverseTransposeShadowLookupMatrix; 103 | 104 | 105 | float4x4 worldOutdoorLookupMatrix VERTEX_REGISTER( c24 ); 106 | float4x4 inverseWorldOutdoorLookupMatrix; 107 | float4x4 transposeWorldOutdoorLookupMatrix; 108 | float4x4 inverseTransposeWorldOutdoorLookupMatrix; 109 | 110 | ////////////////////////////////////////////////////////////// 111 | // GENERAL CONSTANTS ( registers can be changed to fit needs ) 112 | 113 | #define eyePos inverseViewMatrix[3] 114 | 115 | float4 pixelCostDecode; 116 | float4 pixelCostFracs; 117 | float4 debugBumpmap; 118 | 119 | float4 dofEquationViewModelAndFarBlur; 120 | float4 dofEquationScene; 121 | float4 dofLerpScale; 122 | float4 dofLerpBias; 123 | float4 dofRowDelta; 124 | 125 | float4 lightPosition; 126 | float4 lightDiffuse; 127 | float4 lightSpecular; 128 | float4 lightSpotDir; 129 | float4 lightSpotFactors; 130 | float4 lightFalloffPlacement; 131 | 132 | float4 spotShadowmapPixelAdjust; 133 | 134 | float4 glowSetup; 135 | #define GLOW_SETUP_CUTOFF 0 136 | #define GLOW_SETUP_CUTOFF_RESCALE 1 137 | #define GLOW_SETUP_DESATURATION 3 138 | 139 | float4 glowApply; 140 | #define GLOW_APPLY_SKY_BLEED_INTENSITY 0 141 | #define GLOW_APPLY_BLOOM_INTENSITY 3 142 | 143 | // Ingame Shader Manipulation with: 144 | 145 | // glowApply :: Manditory -> r_glowUseTweaks 1 ( !without! r_glowTweakEnable ) 146 | // glowApply.w :: r_glowTweakBloomIntensity0 = 0.0 - 20.0 147 | 148 | // glowSetup :: Manditory -> r_glowUseTweaks 1 ( !without! r_glowTweakEnable ) 149 | // glowSetup.w :: r_glowTweakBloomDesaturation = 0.0 - 1.0 150 | // glowSetup.x :: r_glowTweakBloomCutoff = 0.0 - 1.0; 151 | 152 | // sunSpecular.x :: r_specularColorScale = 0.0 - 100.0; ( influenced by r_lightTweakSunLight ... default sunlight set in radiant, even when dvar > 1.0 counts as 1 ) 153 | 154 | 155 | 156 | float4 baseLightingCoords VERTEX_REGISTER( c8 ); 157 | float4 codeMeshArg[2] VERTEX_REGISTER( c8 ); 158 | 159 | float4 featherParms VERTEX_REGISTER( c12 ); 160 | float4 falloffParms VERTEX_REGISTER( c13 ); // NO PIXEL 161 | float4 falloffBeginColor VERTEX_REGISTER( c14 ); // NO PIXEL 162 | float4 falloffEndColor VERTEX_REGISTER( c15 ); // NO PIXEL 163 | float4 eyeOffsetParms VERTEX_REGISTER( c16 ); // NO PIXEL 164 | 165 | float4 detailScale VERTEX_REGISTER( c12 ); 166 | float4 detailScale1; 167 | float4 detailScale2; 168 | float4 detailScale3; 169 | float4 detailScale4; 170 | 171 | float4 distortionScale VERTEX_REGISTER( c12 ); 172 | float4 nearPlaneOrg VERTEX_REGISTER( c13 ); 173 | float4 nearPlaneDx VERTEX_REGISTER( c14 ); 174 | float4 nearPlaneDy VERTEX_REGISTER( c15 ); 175 | 176 | float4 renderTargetSize VERTEX_REGISTER( c16 ); 177 | float4 particleCloudMatrix VERTEX_REGISTER( c16 ); 178 | float4 clipSpaceLookupScale VERTEX_REGISTER( c17 ); 179 | float4 clipSpaceLookupOffset VERTEX_REGISTER( c18 ); 180 | 181 | float4 depthFromClip VERTEX_REGISTER( c20 ); 182 | float4 fogConsts VERTEX_REGISTER( c21 ); 183 | float4 fogColor VERTEX_REGISTER( c22 ) PIXEL_REGISTER( c0 ); 184 | float4 gameTime VERTEX_REGISTER( c22 ); 185 | // gameTime.w increases linearly forever, and appears to be measured in seconds. 186 | // gameTime.x is a sin wave, amplitude approx 1, period 1. 187 | // gameTime.y is similar, maybe a cos wave? 188 | // gameTime.z goes from 0 to 1 linearly then pops back to 0 once per second 189 | 190 | #define texelSizeX (1.0 / renderTargetSize.x) 191 | #define texelSizeY (1.0 / renderTargetSize.y) 192 | 193 | float4 outdoorFeatherParms; 194 | float4 materialColor PIXEL_REGISTER( c1 ); 195 | float4 shadowmapSwitchPartition PIXEL_REGISTER( c2 ); 196 | float4 shadowmapPolygonOffset PIXEL_REGISTER( c2 ); 197 | float4 particleCloudColor PIXEL_REGISTER( c3 ); 198 | float4 shadowmapScale PIXEL_REGISTER( c4 ); 199 | float4 zNear PIXEL_REGISTER( c4 ); 200 | float4 lightingLookupScale PIXEL_REGISTER( c5 ); 201 | float4 waterColor PIXEL_REGISTER( c6 ); 202 | float4 waterMapParms; 203 | float4 shadowParms; 204 | float4 specularStrength; 205 | 206 | float4 colorMatrixR; 207 | float4 colorMatrixG; 208 | float4 colorMatrixB; 209 | 210 | float4 colorTintBase; 211 | float4 colorTintDelta; 212 | float4 colorBias; 213 | 214 | float4 colorTint; 215 | float4 colorTint1; 216 | float4 colorTint2; 217 | float4 colorTint3; 218 | float4 colorTint4; 219 | 220 | float4 sunPosition PIXEL_REGISTER( c17 ); // r_lighttweaksunposition || sunPosition is light direction 221 | float4 sunDiffuse PIXEL_REGISTER( c18 ); // r_lighttweaksunlight 222 | float4 sunSpecular PIXEL_REGISTER( c19 ); // r_specularcolorscale 223 | 224 | #define ENV_INTENSITY_MIN 0 225 | #define ENV_INTENSITY_MAX 1 226 | #define ENV_EXPONENT 2 227 | #define SUN_INTENSITY_SCALE 3 228 | 229 | float4 envMapParms; 230 | float4 envMapParms1; 231 | float4 envMapParms2; 232 | float4 envMapParms3; 233 | float4 envMapParms4; 234 | 235 | // used for custom code constants ;) 236 | //#if defined( USE_CUSTOM_CONSTANTS ) //&& defined( IS_VERTEX_SHADER ) && IS_VERTEX_SHADER 237 | float4 filterTap[8] : register( c9 ); //VERTEX_REGISTER( c10 ) PIXEL_REGISTER( c20 ); //: register( c10 ); 238 | //#else 239 | // float4 filterTap[8] : register( c12 ); 240 | //#endif 241 | 242 | #define MENU_HIGHLIGHT_RADIUS filterTap[6][0] 243 | #define MENU_HIGHLIGHT_BRIGHTNESS filterTap[6][1] 244 | #define MENU_OUTLINE_RADIUS filterTap[6][2] 245 | #define MENU_OUTLINE_BRIGHTNESS filterTap[6][3] 246 | 247 | #define MENU_MOUSEX filterTap[7][0] 248 | #define MENU_MOUSEY filterTap[7][1] 249 | #define MENU_DBG filterTap[7][2] 250 | #define MENU_TIME filterTap[7][3] 251 | 252 | ///////////////////////////////////////////////////// 253 | // SAMPLERS ( registers can be changed to fit needs ) 254 | 255 | sampler colorMapSampler; // SAMPLER_REGISTER( s0 ); 256 | sampler colorMapSampler1; //SAMPLER_REGISTER( s4 ); 257 | sampler colorMapSampler2; //SAMPLER_REGISTER( s5 ); 258 | sampler colorMapSampler4; 259 | 260 | sampler lightmapSamplerPrimary; //SAMPLER_REGISTER( s2 ); 261 | sampler lightmapSamplerSecondary; //SAMPLER_REGISTER( s3 ); 262 | 263 | sampler dynamicShadowSampler; 264 | sampler shadowCookieSampler; 265 | sampler shadowmapSamplerSun; 266 | sampler shadowmapSamplerSpot; 267 | sampler normalMapSampler; //SAMPLER_REGISTER( s4 ); 268 | sampler normalMapSampler1; 269 | sampler normalMapSampler2; 270 | sampler normalMapSampler3; 271 | sampler normalMapSampler4; 272 | sampler specularMapSampler; 273 | sampler specularMapSampler1; 274 | sampler specularMapSampler2; 275 | sampler specularMapSampler3; 276 | sampler specularMapSampler4; 277 | sampler specularitySampler; 278 | sampler cinematicYSampler; 279 | sampler cinematicCrSampler; 280 | sampler cinematicCbSampler; 281 | sampler cinematicASampler; 282 | sampler attenuationSampler; 283 | 284 | sampler feedbackSampler; 285 | sampler colorMapPostSunSampler; 286 | sampler modelLightingSampler; // SAMPLER_REGISTER( s4 ); 287 | 288 | sampler floatZSampler; 289 | sampler rawFloatZSampler; 290 | sampler processedFloatZSampler; 291 | 292 | sampler outdoorMapSampler; 293 | sampler lookupMapSampler; 294 | 295 | sampler blurSampler; 296 | 297 | sampler detailMapSampler; 298 | sampler detailMapSampler1; 299 | sampler detailMapSampler2; 300 | sampler detailMapSampler3; 301 | sampler detailMapSampler4; 302 | 303 | samplerCUBE skyMapSampler; 304 | samplerCUBE cubeMapSampler; 305 | samplerCUBE reflectionProbeSampler SAMPLER_REGISTER( s1 ); 306 | 307 | 308 | -------------------------------------------------------------------------------- /raw/shader_bin/shader_src/vs_3_0_worldfx_ocean.hlsl: -------------------------------------------------------------------------------- 1 | // * xoxor4d.github.io 2 | // * original shader : https://github.com/tuxalin/water-shader 3 | 4 | #define PC 5 | #define IS_VERTEX_SHADER 1 6 | #define IS_PIXEL_SHADER 0 7 | 8 | // use custom code constants (iw3xo-devgui) 9 | #define USE_CUSTOM_CONSTANTS 10 | 11 | // USE_DISPLACEMENT needs to be defined (utility.hlsl) 12 | #define USE_DISPLACEMENT 13 | #define HIGHTMAP_HASHSCALE .1051 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | // ------------------------------------------ 20 | 21 | struct VertexInput 22 | { 23 | float4 position : POSITION; 24 | float4 color : COLOR; 25 | }; 26 | 27 | struct PixelInput 28 | { 29 | float4 position : POSITION; 30 | float4 color : COLOR; 31 | float3 normal : NORMAL; 32 | float3 uv : TEXCOORD0; 33 | float3 tangent : TEXCOORD1; 34 | float3 bitangent : TEXCOORD2; 35 | float3 worldPos : TEXCOORD3; 36 | float4 projPos : TEXCOORD4; 37 | float4 camPosInvDist: TEXCOORD5; 38 | float3 camPos : TEXCOORD6; 39 | float2 wind : TEXCOORD7; 40 | }; 41 | 42 | // ------------------------------------------ 43 | // we have to create a procedural hightmap since cod4 cannot sample from textures within vertexshader 44 | 45 | float heightmap_hash(in float2 p, in float scale) 46 | { 47 | p = fmod(p, scale); 48 | 49 | float3 p3 = frac(float3(p.xyx) * HIGHTMAP_HASHSCALE); 50 | p3 += dot(p3, p3.yzx + 19.19f); 51 | 52 | return frac((p3.x + p3.y) * p3.z); 53 | } 54 | 55 | static const float2 add = float2(1.0, 0.0); 56 | float heightmap( in float2 x, in float scale, in float time ) 57 | { 58 | x *= scale; 59 | x += time; 60 | 61 | float2 p = floor(x); 62 | float2 f = fract(x); 63 | 64 | f = f * f * (1.5 - f) * 2.0; 65 | 66 | float res = lerp(lerp( heightmap_hash(p, scale), heightmap_hash(p + add.xy, scale), f.x), 67 | lerp( heightmap_hash(p + add.yx, scale), heightmap_hash(p + add.xx, scale), f.x), 68 | f.y); 69 | return res; 70 | } 71 | 72 | // ------------------------------------------ 73 | 74 | PixelInput vs_main( const VertexInput vertex ) 75 | { 76 | PixelInput pixel; 77 | 78 | #ifdef USE_CUSTOM_CONSTANTS 79 | 80 | // both vs / ps 81 | float4 _WaveAmplitude = float4(1 * filterTap[0]); 82 | float4 _WavesIntensity = float4(1 * filterTap[1]); 83 | float4 _WavesNoise = float4(1 * filterTap[2]); 84 | 85 | // vs 86 | float2 _WindDirection = float2(filterTap[3].x, filterTap[3].y); // non-const or custom constants change behaviour 87 | float _HeightIntensity = 1 * filterTap[3].z; 88 | float _WaveAmplitudeFactor = 1 * filterTap[3].w; 89 | 90 | float _WaveSteepness = 1 * filterTap[4].x; 91 | float _TextureTiling = 1 * filterTap[4].y; 92 | float _WaveTiling = 1 * filterTap[4].z; 93 | float _Time = gameTime.w * (1 * filterTap[4].w); 94 | 95 | float _VisibleWaveDist = 1 * filterTap[5].x; 96 | float _HeightMapScale = 1 * filterTap[5].y; 97 | float _HeightMapScroll = gameTime.w * (1 * filterTap[5].z); 98 | 99 | #else // ------------------------------------------ 100 | 101 | // both vs / ps 102 | const float4 _WaveAmplitude = float4(0.72, 0.4, 0.46, 1.93); 103 | float4 _WavesIntensity = float4(0.28, 1.95, 1, 1.9); 104 | float4 _WavesNoise = float4(0.05, 0.45, 1.18, 0.28); 105 | 106 | float2 _WindDirection = float2(-0.85, -3.1); 107 | float _HeightIntensity = 1.1; 108 | const float _WaveAmplitudeFactor = 1.35; 109 | const float _WaveSteepness = 0.65; 110 | const float _TextureTiling = 0.95; 111 | const float _WaveTiling = 0.06; 112 | float _Time = gameTime.w * 0.03; 113 | const float _VisibleWaveDist = 0.2; 114 | const float _HeightMapScale = 4; 115 | float _HeightMapScroll = gameTime.w * 0.15; 116 | 117 | #endif // ifdef USE_CUSTOM_CONSTANTS 118 | 119 | // ------------------------------------------ 120 | // note : this shader was based on Y up, while cod has Z up 121 | 122 | float4 _WorldSpaceCameraPos = inverseWorldMatrix[3]; //inverseViewMatrix[3]; (mix'n match local and modelspace camera) 123 | 124 | float2 windDir = _WindDirection; 125 | float windSpeed = length(_WindDirection); 126 | float timer = _Time * windSpeed * 10; 127 | 128 | windDir /= windSpeed; 129 | 130 | float3 worldPos = vertex.position.xzy; 131 | half3 normal = half3(0, 1, 0); 132 | 133 | float cameraDistance = length(inverseWorldMatrix[3].xzy - worldPos) * _VisibleWaveDist; 134 | float2 noise = GetNoise(worldPos.xz, timer * windDir * 0.5); 135 | 136 | half3 tangent; 137 | float4 waveSettings = float4(windDir, _WaveSteepness, _WaveTiling); 138 | float4 waveAmplitudes = _WaveAmplitude * _WaveAmplitudeFactor; 139 | 140 | worldPos = ComputeDisplacement(worldPos, cameraDistance, noise, timer, waveSettings, waveAmplitudes, _WavesIntensity, _WavesNoise, normal, tangent); 141 | 142 | // add extra noise height from a heightmap 143 | float heightIntensity = _HeightIntensity * (1 - cameraDistance / 100.0) * _WaveAmplitude.x; 144 | float2 texCoord = worldPos.xz * 0.05 *_TextureTiling; 145 | 146 | // cap or we can go negative 147 | if (heightIntensity > 0.02) 148 | { 149 | AdjustWavesValues(noise, _WavesNoise, _WavesIntensity); 150 | 151 | float2 texCoords[4] = { texCoord * 1.6 + timer * 0.064 + _WavesNoise.x, 152 | texCoord * 0.8 + timer * 0.032 + _WavesNoise.y, 153 | texCoord * 0.5 + timer * 0.016 + _WavesNoise.z, 154 | texCoord * 0.3 + timer * 0.008 + _WavesNoise.w }; 155 | 156 | float height = 0; 157 | for (int i = 0; i < 4; ++i) 158 | { 159 | height += (heightmap(texCoords[i], _HeightMapScale, _HeightMapScroll) * _WavesIntensity[i]); 160 | } 161 | 162 | worldPos.y += (height * heightIntensity); 163 | } 164 | 165 | //pixel.position = mul( float4( worldPos.xzy, 1.0f ), worldMatrix ); 166 | //pixel.position = mul( pixel.position, viewProjectionMatrix ); 167 | pixel.position = mul( float4( worldPos.xzy, 1.0f ), worldViewProjectionMatrix ); 168 | 169 | pixel.tangent = tangent; 170 | pixel.bitangent = cross(normal, tangent); 171 | 172 | pixel.uv.xy = worldPos.xz * 0.05 * _TextureTiling; 173 | pixel.uv.z = timer; 174 | 175 | pixel.color = vertex.color; 176 | pixel.normal = normal; 177 | pixel.wind.xy = windDir; 178 | 179 | pixel.camPos.xyz = _WorldSpaceCameraPos.xzy; 180 | 181 | pixel.camPosInvDist.xyz = inverseViewMatrix[3].xyz - mul( float4( worldPos.xzy, 1.0f ), worldMatrix ); 182 | pixel.camPosInvDist.w = distance(worldPos.xzy, inverseWorldMatrix[3]); 183 | 184 | pixel.worldPos = worldPos; 185 | pixel.projPos = Transform_ClipSpacePosToTexCoords(pixel.position); 186 | 187 | return pixel; 188 | } 189 | -------------------------------------------------------------------------------- /raw/shader_bin/shader_src/vs_3_0_worldfx_ocean_unlit.hlsl: -------------------------------------------------------------------------------- 1 | #define PC 2 | #define IS_VERTEX_SHADER 1 3 | #define IS_PIXEL_SHADER 0 4 | 5 | // no support for custom code constants when using fullbright 6 | //#define USE_CUSTOM_CONSTANTS 7 | 8 | // USE_DISPLACEMENT needs to be defined (utility.hlsl) 9 | #define USE_DISPLACEMENT 10 | #define HIGHTMAP_HASHSCALE .1051 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | // almost 1:1 copy of the "lit" ocean vertex shader 17 | 18 | // input struct 19 | struct VertexInput 20 | { 21 | float4 position : POSITION; 22 | }; 23 | 24 | // output struct 25 | struct PixelInput 26 | { 27 | float4 position : POSITION; 28 | float3 normal : NORMAL; 29 | float3 uv : TEXCOORD0; 30 | float3 tangent : TEXCOORD1; 31 | float3 bitangent : TEXCOORD2; 32 | float3 worldPos : TEXCOORD3; 33 | float2 wind : TEXCOORD4; 34 | }; 35 | 36 | // ------------------------------------------ 37 | // we have to create a procedural hightmap since cod4 cannot sample from textures within vertexshader 38 | 39 | float heightmap_hash(in float2 p, in float scale) 40 | { 41 | p = fmod(p, scale); 42 | 43 | float3 p3 = frac(float3(p.xyx) * HIGHTMAP_HASHSCALE); 44 | p3 += dot(p3, p3.yzx + 19.19f); 45 | 46 | return frac((p3.x + p3.y) * p3.z); 47 | } 48 | 49 | static const float2 add = float2(1.0, 0.0); 50 | float heightmap( in float2 x, in float scale, in float time ) 51 | { 52 | x *= scale; 53 | x += time; 54 | 55 | float2 p = floor(x); 56 | float2 f = fract(x); 57 | 58 | f = f * f * (1.5 - f) * 2.0; 59 | 60 | float res = lerp(lerp( heightmap_hash(p, scale), heightmap_hash(p + add.xy, scale), f.x), 61 | lerp( heightmap_hash(p + add.yx, scale), heightmap_hash(p + add.xx, scale), f.x), 62 | f.y); 63 | return res; 64 | } 65 | 66 | // ------------------------------------------ 67 | 68 | PixelInput vs_main( const VertexInput vertex ) 69 | { 70 | PixelInput pixel; 71 | 72 | #ifdef USE_CUSTOM_CONSTANTS 73 | 74 | // both vs / ps 75 | float4 _WaveAmplitude = float4(1 * filterTap[0]); 76 | float4 _WavesIntensity = float4(1 * filterTap[1]); 77 | float4 _WavesNoise = float4(1 * filterTap[2]); 78 | 79 | // vs 80 | float2 _WindDirection = float2(filterTap[3].x, filterTap[3].y); // non-const or custom constants change behaviour 81 | float _HeightIntensity = 1 * filterTap[3].z; 82 | float _WaveAmplitudeFactor = 1 * filterTap[3].w; 83 | 84 | float _WaveSteepness = 1 * filterTap[4].x; 85 | float _TextureTiling = 1 * filterTap[4].y; 86 | float _WaveTiling = 1 * filterTap[4].z; 87 | float _Time = gameTime.w * (1 * filterTap[4].w); 88 | 89 | float _VisibleWaveDist = 1 * filterTap[5].x; 90 | float _HeightMapScale = 1 * filterTap[5].y; 91 | float _HeightMapScroll = gameTime.w * (1 * filterTap[5].z); 92 | 93 | #else // ------------------------------------------ 94 | 95 | // both vs / ps 96 | const float4 _WaveAmplitude = float4(0.72, 0.4, 0.46, 1.93); 97 | float4 _WavesIntensity = float4(0.28, 1.95, 1, 1.9); 98 | float4 _WavesNoise = float4(0.05, 0.45, 1.18, 0.28); 99 | 100 | float2 _WindDirection = float2(-0.85, -3.1); 101 | float _HeightIntensity = 1.1; 102 | const float _WaveAmplitudeFactor = 1.35; 103 | const float _WaveSteepness = 0.65; 104 | const float _TextureTiling = 0.95; 105 | const float _WaveTiling = 0.06; 106 | float _Time = gameTime.w * 0.03; 107 | const float _VisibleWaveDist = 0.2; 108 | const float _HeightMapScale = 4; 109 | float _HeightMapScroll = gameTime.w * 0.15; 110 | 111 | #endif // ifdef USE_CUSTOM_CONSTANTS 112 | 113 | // ------------------------------------------ 114 | // note : this shader was based on Y up, while cod has Z up 115 | 116 | float4 _WorldSpaceCameraPos = inverseWorldMatrix[3]; //inverseViewMatrix[3]; (mix'n match local and modelspace camera) 117 | 118 | float2 windDir = _WindDirection; 119 | float windSpeed = length(_WindDirection); 120 | float timer = _Time * windSpeed * 10; 121 | 122 | windDir /= windSpeed; 123 | 124 | float3 worldPos = vertex.position.xzy; 125 | half3 normal = half3(0, 1, 0); 126 | 127 | float cameraDistance = length(inverseWorldMatrix[3].xzy - worldPos) * _VisibleWaveDist; 128 | float2 noise = GetNoise(worldPos.xz, timer * windDir * 0.5); 129 | 130 | half3 tangent; 131 | float4 waveSettings = float4(windDir, _WaveSteepness, _WaveTiling); 132 | float4 waveAmplitudes = _WaveAmplitude * _WaveAmplitudeFactor; 133 | 134 | worldPos = ComputeDisplacement(worldPos, cameraDistance, noise, timer, waveSettings, waveAmplitudes, _WavesIntensity, _WavesNoise, normal, tangent); 135 | 136 | // add extra noise height from a heightmap 137 | float heightIntensity = _HeightIntensity * (1 - cameraDistance / 100.0) * _WaveAmplitude.x; 138 | float2 texCoord = worldPos.xz * 0.05 *_TextureTiling; 139 | 140 | // cap or we can go negative 141 | if (heightIntensity > 0.02) 142 | { 143 | AdjustWavesValues(noise, _WavesNoise, _WavesIntensity); 144 | 145 | float2 texCoords[4] = { texCoord * 1.6 + timer * 0.064 + _WavesNoise.x, 146 | texCoord * 0.8 + timer * 0.032 + _WavesNoise.y, 147 | texCoord * 0.5 + timer * 0.016 + _WavesNoise.z, 148 | texCoord * 0.3 + timer * 0.008 + _WavesNoise.w }; 149 | 150 | float height = 0; 151 | for (int i = 0; i < 4; ++i) 152 | { 153 | height += (heightmap(texCoords[i], _HeightMapScale, _HeightMapScroll) * _WavesIntensity[i]); 154 | } 155 | 156 | worldPos.y += (height * heightIntensity); 157 | } 158 | 159 | pixel.uv.xy = worldPos.xz * 0.05 * _TextureTiling; 160 | pixel.uv.z = timer; 161 | pixel.normal = normal; 162 | 163 | pixel.tangent = tangent; 164 | pixel.bitangent = cross(normal, tangent); 165 | 166 | pixel.wind = windDir; 167 | 168 | pixel.position = mul( float4( worldPos.xzy, 1.0f ), worldViewProjectionMatrix ); 169 | pixel.worldPos = normalize(inverseWorldMatrix[3] - vertex.position.xyz); 170 | 171 | return pixel; 172 | } -------------------------------------------------------------------------------- /raw/statemaps/water.sm: -------------------------------------------------------------------------------- 1 | alphaTest 2 | { 3 | default: 4 | Always; 5 | } 6 | 7 | blendFunc 8 | { 9 | default: 10 | passthrough; 11 | } 12 | 13 | separateAlphaBlendFunc 14 | { 15 | default: 16 | Disable, One, Zero; 17 | } 18 | 19 | cullFace 20 | { 21 | default: 22 | passthrough; 23 | } 24 | 25 | depthTest 26 | { 27 | default: 28 | passthrough; 29 | } 30 | 31 | depthWrite 32 | { 33 | default: 34 | passthrough; 35 | } 36 | 37 | colorWrite 38 | { 39 | default: 40 | Enable, Disable; 41 | } 42 | 43 | polygonOffset 44 | { 45 | default: 46 | passthrough; 47 | } 48 | 49 | stencil 50 | { 51 | default: 52 | Disable, 53 | Always, Zero, Zero, Zero, 54 | Always, Zero, Zero, Zero; 55 | } 56 | 57 | wireframe 58 | { 59 | default: 60 | Disable; 61 | } 62 | -------------------------------------------------------------------------------- /raw/techniques/worldfx_ocean.tech: -------------------------------------------------------------------------------- 1 | // * xoxor4d.github.io/projects/cod4-ocean/ 2 | // * original shader : https://github.com/tuxalin/water-shader 3 | 4 | { 5 | stateMap "water"; 6 | 7 | vertexShader 3.0 "worldfx_ocean" 8 | { 9 | } 10 | 11 | pixelShader 3.0 "worldfx_ocean" 12 | { 13 | skyMapSampler = material.colorMap; // cubemap for radiance and or reflection 14 | normalMapSampler = material.normalMap; // water normal 15 | specularMapSampler = material.specularMap; // rgb = foam; alpha = heightmap 16 | colorMapPostSunSampler = sampler.resolvedPostSun; // framebuffer for refraction 17 | } 18 | 19 | vertex.position = code.position; 20 | vertex.color[0] = code.color; 21 | } -------------------------------------------------------------------------------- /raw/techniques/worldfx_ocean_unlit.tech: -------------------------------------------------------------------------------- 1 | // * xoxor4d.github.io/projects/cod4-ocean/ 2 | // * original shader : https://github.com/tuxalin/water-shader 3 | 4 | { 5 | stateMap "default"; 6 | 7 | vertexShader 3.0 "worldfx_ocean_unlit" 8 | { 9 | } 10 | 11 | pixelShader 3.0 "worldfx_ocean_unlit" 12 | { 13 | skyMapSampler = material.colorMap; // cubemap for radiance and or reflection 14 | normalMapSampler = material.normalMap; // water normal 15 | } 16 | 17 | vertex.position = code.position; 18 | } -------------------------------------------------------------------------------- /raw/techsets/mc_worldfx_ocean.techset: -------------------------------------------------------------------------------- 1 | "solid wireframe": 2 | wireframe_solid_dtex; 3 | 4 | "fakelight normal": 5 | "fakelight view": 6 | "unlit": 7 | worldfx_ocean_unlit; 8 | 9 | "emissive shadow": 10 | "emissive": 11 | worldfx_ocean; 12 | -------------------------------------------------------------------------------- /raw/techsets/sm2/mc_worldfx_ocean.techset: -------------------------------------------------------------------------------- 1 | "solid wireframe": 2 | wireframe_solid_dtex; 3 | 4 | "fakelight normal": 5 | "fakelight view": 6 | "unlit": 7 | worldfx_ocean_unlit; 8 | 9 | "emissive shadow": 10 | "emissive": 11 | worldfx_ocean; 12 | -------------------------------------------------------------------------------- /raw/techsets/sm2/wc_worldfx_ocean.techset: -------------------------------------------------------------------------------- 1 | "solid wireframe": 2 | wireframe_solid; 3 | 4 | "fakelight normal": 5 | "fakelight view": 6 | "unlit": 7 | worldfx_ocean_unlit; 8 | 9 | "emissive shadow": 10 | "emissive": 11 | worldfx_ocean; 12 | -------------------------------------------------------------------------------- /raw/techsets/sm2/worldfx_ocean.techset: -------------------------------------------------------------------------------- 1 | "solid wireframe": 2 | wireframe_solid; 3 | 4 | "fakelight normal": 5 | "fakelight view": 6 | "unlit": 7 | worldfx_ocean_unlit; 8 | 9 | "emissive shadow": 10 | "emissive": 11 | worldfx_ocean; 12 | -------------------------------------------------------------------------------- /raw/techsets/wc_worldfx_ocean.techset: -------------------------------------------------------------------------------- 1 | "solid wireframe": 2 | wireframe_solid; 3 | 4 | "fakelight normal": 5 | "fakelight view": 6 | "unlit": 7 | worldfx_ocean_unlit; 8 | 9 | "emissive shadow": 10 | "emissive": 11 | worldfx_ocean; 12 | -------------------------------------------------------------------------------- /raw/techsets/worldfx_ocean.techset: -------------------------------------------------------------------------------- 1 | "solid wireframe": 2 | wireframe_solid; 3 | 4 | "fakelight normal": 5 | "fakelight view": 6 | "unlit": 7 | worldfx_ocean_unlit; 8 | 9 | "emissive shadow": 10 | "emissive": 11 | worldfx_ocean; 12 | -------------------------------------------------------------------------------- /source_data/shader_ocean.gdt: -------------------------------------------------------------------------------- 1 | { 2 | "dynamic_ocean" ( "material.gdf" ) 3 | { 4 | "template" "material.template" 5 | "materialType" "custom" 6 | "locale_case" "1" 7 | "locale_test" "0" 8 | "locale_tools" "0" 9 | "locale_decal" "0" 10 | "locale_Middle_East" "0" 11 | "locale_London" "0" 12 | "locale_Kiev" "0" 13 | "locale_Chechnya" "0" 14 | "locale_Generic" "0" 15 | "locale_Duhoc" "0" 16 | "locale_Villers" "0" 17 | "locale_Egypt" "0" 18 | "locale_Libya" "0" 19 | "locale_Tunisia" "0" 20 | "locale_Industrial" "0" 21 | "locale_Poland" "0" 22 | "locale_Modern_America" "0" 23 | "usage" "case" 24 | "surfaceType" "water" 25 | "missileClip" "0" 26 | "bulletClip" "0" 27 | "playerClip" "0" 28 | "aiClip" "0" 29 | "vehicleClip" "0" 30 | "itemClip" "0" 31 | "canShootClip" "0" 32 | "aiSightClip" "0" 33 | "noFallDamage" "1" 34 | "noSteps" "1" 35 | "noImpact" "0" 36 | "noMarks" "0" 37 | "noPenetrate" "0" 38 | "noDrop" "0" 39 | "slick" "0" 40 | "ladder" "0" 41 | "mantleOn" "0" 42 | "mantleOver" "0" 43 | "noLightmap" "1" 44 | "noDynamicLight" "0" 45 | "noCastShadow" "0" 46 | "noReceiveDynamicShadow" "0" 47 | "noDraw" "0" 48 | "noFog" "0" 49 | "drawToggle" "0" 50 | "sky" "0" 51 | "radialNormals" "0" 52 | "nonColliding" "1" 53 | "nonSolid" "1" 54 | "transparent" "0" 55 | "detail" "1" 56 | "structural" "0" 57 | "portal" "0" 58 | "lightPortal" "0" 59 | "origin" "0" 60 | "physicsGeom" "0" 61 | "hdrPortal" "0" 62 | "hasEditorMaterial" "0" 63 | "zFeather" "1" 64 | "zFeatherDepth" "39" 65 | "eyeOffsetDepth" "0" 66 | "outdoorOnly" "0" 67 | "falloff" "0" 68 | "falloffBeginAngle" "35" 69 | "falloffEndAngle" "65" 70 | "useSpotLight" "0" 71 | "distFalloff" "0" 72 | "distFalloffBeginDistance" "200" 73 | "distFalloffEndDistance" "10" 74 | "falloffBeginColor" "1.000000 1.000000 1.000000 1.000000" 75 | "falloffEndColor" "0.500000 0.500000 0.500000 0.500000" 76 | "texScroll" "0" 77 | "detailScaleX" "8" 78 | "detailScaleY" "8" 79 | "envMapMin" "0.2" 80 | "envMapMax" "1.5" 81 | "envMapExponent" "2.5" 82 | "useLegacyNormalEncoding" "0" 83 | "sort" "*" 84 | "customTemplate" "_ocean" 85 | "customString" "worldfx_ocean" 86 | "colorTint" "0.776471 0.925490 1.000000 1.000000" 87 | "colorMap" "texture_assets\\surf\\ocean\\surf_ocean_cube_ft.tga" 88 | "detailMap" "" 89 | "normalMap" "texture_assets\\surf\\ocean\\surf_ocean_normal.tga" 90 | "specColorMap" "texture_assets\\surf\\ocean\\surf_ocean_foam_as_spec.tga" 91 | "cosinePowerMap" "texture_assets\\surf\\ocean\\surf_ocean_height_as_cosine.tga" 92 | "specColorStrength" "100" 93 | "cosinePowerStrength" "100" 94 | "tileColor" "tile both*" 95 | "tileNormal" "tile both*" 96 | "tileSpecular" "tile both*" 97 | "filterColor" "nomip bilinear" 98 | "filterDetail" "mip standard (2x bilinear)*" 99 | "filterNormal" "nomip bilinear" 100 | "filterSpecular" "nomip bilinear" 101 | "nopicmipColor" "1" 102 | "nopicmipDetail" "0" 103 | "nopicmipNormal" "0" 104 | "nopicmipSpecular" "0" 105 | "noStreamColor" "0" 106 | "tessSize" "0" 107 | "textureAtlasRowCount" "1" 108 | "textureAtlasColumnCount" "1" 109 | "distortionScaleX" "0.5" 110 | "distortionScaleY" "0" 111 | "distortionColorBehavior" "scales distortion strength*" 112 | "waterMapTextureWidth" "64" 113 | "waterMapHorizontalWorldLength" "37" 114 | "waterMapVerticalWorldLength" "37" 115 | "waterMapWindSpeed" "76" 116 | "waterMapWindDirectionX" "1" 117 | "waterMapWindDirectionY" "0" 118 | "waterMapAmplitude" "0.06" 119 | "waterColorR" "0.2" 120 | "waterColorG" "0.3" 121 | "waterColorB" "0.4" 122 | "formatColor" "*" 123 | "formatDetail" "*" 124 | "formatSpecular" "*" 125 | "formatNormal" "*" 126 | "wireframe" "Disable*" 127 | "blendFunc" "Blend" 128 | "customBlendOpRgb" "Add*" 129 | "customBlendOpAlpha" "Add*" 130 | "srcCustomBlendFunc" "One*" 131 | "destCustomBlendFunc" "One*" 132 | "srcCustomBlendFuncAlpha" "One*" 133 | "destCustomBlendFuncAlpha" "One*" 134 | "alphaTest" "Always*" 135 | "depthTest" "LessEqual*" 136 | "depthWrite" "On" 137 | "cullFace" "None" 138 | "polygonOffset" "None*" 139 | "showAdvancedOptions" "*" 140 | "colorWriteRed" "Enable" 141 | "colorWriteGreen" "Enable" 142 | "colorWriteBlue" "Enable" 143 | "colorWriteAlpha" "Enable" 144 | "stencilOpFail1" "Replace" 145 | "stencilOpZFail1" "Replace" 146 | "stencilOpPass1" "Replace" 147 | "stencilOpFail2" "Keep" 148 | "stencilOpZFail2" "Keep" 149 | "stencilOpPass2" "Keep" 150 | "stencilFunc1" "NotEqual" 151 | "stencilFunc2" "Always" 152 | "stencil" "Disable" 153 | } 154 | "ocean_plane" ( "xmodel.gdf" ) 155 | { 156 | "type" "rigid" 157 | "filename" "shader-ocean\\ocean_plane.xmodel_export" 158 | "highLodDist" "0" 159 | "forceMediumLodRigid" "0" 160 | "mediumLod" "" 161 | "mediumLodDist" "0" 162 | "forceLowLodRigid" "0" 163 | "lowLod" "" 164 | "lowLodDist" "0" 165 | "forceLowestLodRigid" "0" 166 | "lowestLod" "" 167 | "lowestLodDist" "0" 168 | "groundLit" "0" 169 | "noRadialNormals" "0" 170 | "radialOriginX" "0" 171 | "radialOriginY" "0" 172 | "radialOriginZ" "0" 173 | "allowHidingAllParts" "0" 174 | "collisionLOD" "None" 175 | "hitBoxModel" "" 176 | "skinOverride" "" 177 | "boneControllers" "" 178 | "boneStabilizers" "" 179 | "physicsPreset" "" 180 | } 181 | } -------------------------------------------------------------------------------- /texture_assets/shader_ocean/surf_ocean_cube_bk.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoxor4d/cod4-shader-ocean/122716e5d96066c44a265fba6e3789a405a17d29/texture_assets/shader_ocean/surf_ocean_cube_bk.tga -------------------------------------------------------------------------------- /texture_assets/shader_ocean/surf_ocean_cube_ft.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoxor4d/cod4-shader-ocean/122716e5d96066c44a265fba6e3789a405a17d29/texture_assets/shader_ocean/surf_ocean_cube_ft.tga -------------------------------------------------------------------------------- /texture_assets/shader_ocean/surf_ocean_cube_lf.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoxor4d/cod4-shader-ocean/122716e5d96066c44a265fba6e3789a405a17d29/texture_assets/shader_ocean/surf_ocean_cube_lf.tga -------------------------------------------------------------------------------- /texture_assets/shader_ocean/surf_ocean_cube_rt.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoxor4d/cod4-shader-ocean/122716e5d96066c44a265fba6e3789a405a17d29/texture_assets/shader_ocean/surf_ocean_cube_rt.tga -------------------------------------------------------------------------------- /texture_assets/shader_ocean/surf_ocean_cube_up.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoxor4d/cod4-shader-ocean/122716e5d96066c44a265fba6e3789a405a17d29/texture_assets/shader_ocean/surf_ocean_cube_up.tga -------------------------------------------------------------------------------- /texture_assets/shader_ocean/surf_ocean_foam_as_spec.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoxor4d/cod4-shader-ocean/122716e5d96066c44a265fba6e3789a405a17d29/texture_assets/shader_ocean/surf_ocean_foam_as_spec.tga -------------------------------------------------------------------------------- /texture_assets/shader_ocean/surf_ocean_height_as_cosine.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoxor4d/cod4-shader-ocean/122716e5d96066c44a265fba6e3789a405a17d29/texture_assets/shader_ocean/surf_ocean_height_as_cosine.tga -------------------------------------------------------------------------------- /texture_assets/shader_ocean/surf_ocean_normal.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoxor4d/cod4-shader-ocean/122716e5d96066c44a265fba6e3789a405a17d29/texture_assets/shader_ocean/surf_ocean_normal.tga --------------------------------------------------------------------------------