1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| CCEffect %{ techniques: - name: ocean-water passes: - vert: ocean-vs:vert frag: ocean-fs:frag properties: &props waterTexture: { value: white } normalTexture: { value: grey } foamTexture: { value: white } skyboxTexture: { value: white } deepOceanColor: { value: [0, 0.05, 0.2, 1], editor: { type: color } } shallowOceanColor:{ value: [0, 0.3, 0.6, 1], editor: { type: color } } foamColor: { value: [1, 1, 1, 1], editor: { type: color } } waveHeight: { value: 0.2, range: [0, 1] } waveScale: { value: 2.0, range: [0.1, 10] } waveSpeed: { value: 1.0, range: [0, 5] } windDirection: { value: [1, 0], editor: { type: vec2 } } foamThreshold: { value: 0.7, range: [0, 1] } reflectionStrength: { value: 0.8, range: [0, 1] } }%
CCProgram ocean-vs %{ #include <surface-vertex> uniform float waveHeight; uniform float waveScale; uniform float waveSpeed; uniform vec2 windDirection; out vec3 v_waveDisplacement; void vert() { SurfaceIn surfaceIn; VertexInput(surfaceIn); vec3 worldPos = (cc_matWorld * vec4(surfaceIn.position.xyz, 1.0)).xyz; vec2 windDir = normalize(windDirection); float time = cc_time.x * waveSpeed; vec3 displacement = vec3(0.0); float phase1 = dot(windDir, worldPos.xz) * waveScale + time; displacement.y += waveHeight * sin(phase1); displacement.xz += waveHeight * 0.3 * cos(phase1) * windDir; vec2 dir2 = normalize(windDir + vec2(0.3, -0.2)); float phase2 = dot(dir2, worldPos.xz) * waveScale * 1.3 + time * 0.9; displacement.y += waveHeight * 0.7 * sin(phase2); displacement.xz += waveHeight * 0.2 * cos(phase2) * dir2; vec2 dir3 = normalize(windDir + vec2(-0.4, 0.3)); float phase3 = dot(dir3, worldPos.xz) * waveScale * 2.1 + time * 1.2; displacement.y += waveHeight * 0.4 * sin(phase3); displacement.xz += waveHeight * 0.1 * cos(phase3) * dir3; worldPos += displacement; v_waveDisplacement = displacement; surfaceIn.position = vec4((inverse(cc_matWorld) * vec4(worldPos, 1.0)).xyz, 1.0); SurfaceVertex(surfaceIn); } }%
CCProgram ocean-fs %{ #include <surface-fragment> uniform sampler2D waterTexture; uniform sampler2D normalTexture; uniform sampler2D foamTexture; uniform samplerCube skyboxTexture; uniform vec4 deepOceanColor; uniform vec4 shallowOceanColor; uniform vec4 foamColor; uniform float foamThreshold; uniform float reflectionStrength; in vec3 v_waveDisplacement; void surf(in SurfaceIn In, inout SurfaceOut Out) { vec2 uv1 = In.uv * 2.0 + cc_time.x * vec2(0.02, 0.01); vec2 uv2 = In.uv * 1.5 - cc_time.x * vec2(0.015, 0.025); vec3 normal1 = texture(normalTexture, uv1).xyz * 2.0 - 1.0; vec3 normal2 = texture(normalTexture, uv2).xyz * 2.0 - 1.0; vec3 oceanNormal = normalize(normal1 + normal2 * 0.8); float waveIntensity = length(v_waveDisplacement); float foamFactor = smoothstep(foamThreshold, 1.0, waveIntensity); vec4 foam = texture(foamTexture, uv1 * 3.0) * foamColor; foam *= sin(cc_time.x * 2.0 + In.uv.x * 15.0) * 0.3 + 0.7; vec3 viewDir = normalize(cc_cameraPos.xyz - In.worldPos); vec3 worldNormal = transformNormalToWorld(In, oceanNormal); vec3 reflectDir = reflect(-viewDir, worldNormal); vec4 skyReflection = textureCube(skyboxTexture, reflectDir); float fresnel = pow(1.0 - max(dot(worldNormal, viewDir), 0.0), 2.0); vec4 oceanColor = mix(shallowOceanColor, deepOceanColor, fresnel); vec4 finalColor = mix(oceanColor, skyReflection, fresnel * reflectionStrength); finalColor = mix(finalColor, foam, foamFactor); Out.albedo = finalColor; Out.normal = worldNormal; Out.metallic = 0.0; Out.roughness = 0.05; Out.emissive = vec3(0.0); Out.ao = 1.0; } vec3 transformNormalToWorld(SurfaceIn In, vec3 tangentNormal) { vec3 N = normalize(In.worldNormal); vec3 T = normalize(In.worldTangent.xyz); vec3 B = normalize(cross(N, T)) * In.worldTangent.w; mat3 TBN = mat3(T, B, N); return normalize(TBN * tangentNormal); } }%
|