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
| CCEffect %{ techniques: - name: procedural passes: - vert: procedural-vs:vert frag: procedural-fs:frag properties: &props scale: { value: 10.0, range: [1, 100] } lacunarity: { value: 2.0, range: [1, 5] } persistence: { value: 0.5, range: [0.1, 1] } octaves: { value: 4, range: [1, 8] } color1: { value: [0.2, 0.1, 0.05, 1], editor: { type: color } } color2: { value: [0.8, 0.6, 0.4, 1], editor: { type: color } } noiseOffset: { value: [0, 0], editor: { type: vec2 } } }%
CCProgram procedural-vs %{ #include <surface-vertex> }%
CCProgram procedural-fs %{ #include <surface-fragment> uniform float scale; uniform float lacunarity; uniform float persistence; uniform int octaves; uniform vec4 color1; uniform vec4 color2; uniform vec2 noiseOffset; void surf(in SurfaceIn In, inout SurfaceOut Out) { float noise = fbmNoise(noiseUV, octaves, lacunarity, persistence); vec4 albedo = mix(color1, color2, noise); float roughnessValue = mix(0.2, 0.8, noise); Out.albedo = albedo; Out.normal = transformNormalToWorld(In, normal); Out.metallic = 0.0; Out.roughness = roughnessValue; Out.emissive = vec3(0.0); Out.ao = 1.0; } float random(vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123); } float noise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); float a = random(i); float b = random(i + vec2(1.0, 0.0)); float c = random(i + vec2(0.0, 1.0)); float d = random(i + vec2(1.0, 1.0)); vec2 u = f * f * (3.0 - 2.0 * f); return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } float fbmNoise(vec2 st, int octaves, float lacunarity, float persistence) { float value = 0.0; float amplitude = 1.0; float frequency = 1.0; for (int i = 0; i < octaves; i++) { value += amplitude * noise(st * frequency); amplitude *= persistence; frequency *= lacunarity; } return value; } vec3 calculateProceduralNormal(vec2 uv) { float eps = 0.01; float heightL = fbmNoise(uv - vec2(eps, 0.0), octaves, lacunarity, persistence); float heightR = fbmNoise(uv + vec2(eps, 0.0), octaves, lacunarity, persistence); float heightD = fbmNoise(uv - vec2(0.0, eps), octaves, lacunarity, persistence); float heightU = fbmNoise(uv + vec2(0.0, eps), octaves, lacunarity, persistence); vec3 normal; normal.x = (heightL - heightR) / (2.0 * eps); normal.y = (heightD - heightU) / (2.0 * eps); normal.z = 1.0; return normalize(normal); } vec3 transformNormalToWorld(SurfaceIn In, vec3 tangentNormal) { vec3 N = normalize(In.worldNormal); vec3 T = normalize(In.worldTangent.xyz); vec3 B = normalize(In.worldBinormal); mat3 TBN = mat3(T, B, N); return normalize(TBN * tangentNormal); } }%
|