genuary1.c (11492B)
1 #include "raylib.h" 2 #include "raymath.h" 3 #include "rlgl.h" 4 #include <math.h> 5 6 #define SCREEN_WIDTH 1000 7 #define SCREEN_HEIGHT 1000 8 9 #define FIELD_SIZE 64 10 #define CHAIN_HEIGHT 1024 11 #define MAX_INSTANCES ((FIELD_SIZE * 2) * (FIELD_SIZE * 2) * CHAIN_HEIGHT / 2) 12 13 #define CUBE_SIZE 0.5f 14 #define VERTICAL_SPACING (CUBE_SIZE * 1.7320508f) 15 #define SPACING 8.0f 16 17 #define TILT_STRENGTH 0.30f 18 #define OFFSET_STRENGTH 3.00f 19 20 #define FADE_START_DISTANCE SPACING * 2 21 #define FADE_END_DISTANCE SPACING * 8 22 #define RENDER_CULL_DISTANCE FADE_END_DISTANCE 23 #define RENDER_CULL_SQ (RENDER_CULL_DISTANCE * RENDER_CULL_DISTANCE) 24 25 #define HUE 91.0f 26 #define SATURATION 0.15f 27 #define VALUE 0.78f 28 29 #define HASH(x, z) \ 30 (((x) * 73856093u ^ (z) * 19349663u) * 0x85ebca6b & 0x7FFFFFFF) / \ 31 (float)0x7FFFFFFF 32 33 const char *vsCode = 34 "#version 330\n" 35 "layout(location = 0) in vec3 vertexPosition;\n" 36 "layout(location = 1) in vec2 vertexTexCoord;\n" 37 "layout(location = 2) in vec3 vertexNormal;\n" 38 "layout(location = 3) in mat4 instanceTransform;\n" 39 "\n" 40 "uniform mat4 mvp;\n" 41 "\n" 42 "out vec3 fragPosition;\n" 43 "\n" 44 "void main() {\n" 45 " vec4 worldPos = instanceTransform * vec4(vertexPosition, 1.0);\n" 46 " fragPosition = vec3(worldPos);\n" 47 " gl_Position = mvp * worldPos;\n" 48 "}\n"; 49 50 const char *fsCode = "#version 330\n" 51 "in vec3 fragPosition;\n" 52 "out vec4 finalColor;\n" 53 "\n" 54 "uniform vec3 viewPos;\n" 55 "uniform float fadeStart;\n" 56 "uniform float fadeEnd;\n" 57 "uniform vec3 baseColor;\n" 58 "\n" 59 "const float bayer8x8[64] = float[](\n" 60 " 0.0, 32.0, 8.0, 40.0, 2.0, 34.0, 10.0, 42.0,\n" 61 " 48.0, 16.0, 56.0, 24.0, 50.0, 18.0, 58.0, 26.0,\n" 62 " 12.0, 44.0, 4.0, 36.0, 14.0, 46.0, 6.0, 38.0,\n" 63 " 60.0, 28.0, 52.0, 20.0, 62.0, 30.0, 54.0, 22.0,\n" 64 " 3.0, 35.0, 11.0, 43.0, 1.0, 33.0, 9.0, 41.0,\n" 65 " 51.0, 19.0, 59.0, 27.0, 49.0, 17.0, 57.0, 25.0,\n" 66 " 15.0, 47.0, 7.0, 39.0, 13.0, 45.0, 5.0, 37.0,\n" 67 " 63.0, 31.0, 55.0, 23.0, 61.0, 29.0, 53.0, 21.0\n" 68 ");\n" 69 "\n" 70 "void main() {\n" 71 " float dist = distance(fragPosition, viewPos);\n" 72 " float intensity = 1.0 - clamp((dist - fadeStart) / " 73 "(fadeEnd - fadeStart), 0.0, 1.0);\n" 74 "\n" 75 " int x = int(gl_FragCoord.x) % 8;\n" 76 " int y = int(gl_FragCoord.y) % 8;\n" 77 " float rawValue = bayer8x8[y * 8 + x];\n" 78 " float threshold = (rawValue + 0.5) / 64.0;\n" 79 " if (intensity < threshold) {\n" 80 " finalColor = vec4(0.0, 0.0, 0.0, 1.0);\n" 81 " } else {\n" 82 " finalColor = vec4(baseColor, 1.0);\n" 83 " }\n" 84 "}\n"; 85 86 const char *liquifyFsCode = 87 "#version 330\n" 88 "in vec2 fragTexCoord;\n" 89 "in vec4 fragColor;\n" 90 "out vec4 finalColor;\n" 91 "\n" 92 "uniform sampler2D texture0;\n" 93 "uniform vec4 colDiffuse;\n" 94 "uniform vec2 center1;\n" 95 "uniform vec2 center2;\n" 96 "uniform vec2 screenSize;\n" 97 "\n" 98 "const float radius = 1.80;\n" 99 "const float strength = 0.10;\n" 100 "\n" 101 "vec2 calculateDistortion(vec2 uv, vec2 center) {\n" 102 " float aspect = screenSize.x / screenSize.y;\n" 103 " vec2 uvCorrected = uv;\n" 104 " uvCorrected.x *= aspect;\n" 105 " vec2 centerCorrected = center;\n" 106 " centerCorrected.x *= aspect;\n" 107 "\n" 108 " vec2 delta = uvCorrected - centerCorrected;\n" 109 " float dist = length(delta);\n" 110 " \n" 111 " // Smoothstep creates a soft edge 0.0 to radius\n" 112 " float mask = 1.0 - smoothstep(0.0, radius, dist);\n" 113 " \n" 114 " // Distort UV towards the center point\n" 115 " return (uv - center) * mask * strength;\n" 116 "}\n" 117 "\n" 118 "void main() {\n" 119 " vec2 uv = fragTexCoord;\n" 120 " vec2 offset1 = calculateDistortion(uv, center1);\n" 121 " vec2 offset2 = calculateDistortion(uv, center2);\n" 122 " uv -= (offset1 + offset2);\n" 123 " finalColor = texture(texture0, uv) * colDiffuse * fragColor;\n" 124 "}\n"; 125 126 Matrix transforms[MAX_INSTANCES]; 127 128 Vector2 GetPerimeterPosition(float t) { 129 float cycle = fmodf(t / 100, 4.0f); 130 131 if (cycle < 1.0f) { 132 return (Vector2){cycle, 0.0f}; 133 } else if (cycle < 2.0f) { 134 return (Vector2){1.0f, cycle - 1.0f}; 135 } else if (cycle < 3.0f) { 136 return (Vector2){1.0f - (cycle - 2.0f), 1.0f}; 137 } else { 138 return (Vector2){0.0f, 1.0f - (cycle - 3.0f)}; 139 } 140 } 141 142 int main(void) { 143 SetConfigFlags(FLAG_WINDOW_RESIZABLE); 144 InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "GENUARY 1. ONE SHAPE, ONE COLOR"); 145 146 Camera3D camera = {0}; 147 camera.up = (Vector3){0.0f, 1.0f, 0.0f}; 148 camera.fovy = 30.0f; 149 camera.projection = CAMERA_PERSPECTIVE; 150 151 SetTargetFPS(144); 152 153 Shader ditherShader = LoadShaderFromMemory(vsCode, fsCode); 154 ditherShader.locs[SHADER_LOC_MATRIX_MVP] = 155 GetShaderLocation(ditherShader, "mvp"); 156 ditherShader.locs[SHADER_LOC_VECTOR_VIEW] = 157 GetShaderLocation(ditherShader, "viewPos"); 158 ditherShader.locs[SHADER_LOC_MATRIX_MODEL] = 3; 159 160 int fadeStartLoc = GetShaderLocation(ditherShader, "fadeStart"); 161 int fadeEndLoc = GetShaderLocation(ditherShader, "fadeEnd"); 162 int colorLoc = GetShaderLocation(ditherShader, "baseColor"); 163 float fadeStartVal = FADE_START_DISTANCE; 164 float fadeEndVal = FADE_END_DISTANCE; 165 Color c = ColorFromHSV(HUE, SATURATION, VALUE); 166 Vector3 colorVal = {(float)c.r / 255.0f, (float)c.g / 255.0f, 167 (float)c.b / 255.0f}; 168 SetShaderValue(ditherShader, fadeStartLoc, &fadeStartVal, 169 SHADER_UNIFORM_FLOAT); 170 SetShaderValue(ditherShader, fadeEndLoc, &fadeEndVal, SHADER_UNIFORM_FLOAT); 171 SetShaderValue(ditherShader, colorLoc, &colorVal, SHADER_UNIFORM_VEC3); 172 173 Shader liquifyShader = LoadShaderFromMemory(0, liquifyFsCode); 174 int locCenter1 = GetShaderLocation(liquifyShader, "center1"); 175 int locCenter2 = GetShaderLocation(liquifyShader, "center2"); 176 int locScreenSize = GetShaderLocation(liquifyShader, "screenSize"); 177 178 RenderTexture2D target = 179 LoadRenderTexture(GetScreenWidth(), GetScreenHeight()); 180 Vector2 currentScreenSize = {(float)GetScreenWidth(), 181 (float)GetScreenHeight()}; 182 SetShaderValue(liquifyShader, locScreenSize, ¤tScreenSize, 183 SHADER_UNIFORM_VEC2); 184 185 Mesh cubeMesh = GenMeshCube(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE); 186 Material cubeMat = LoadMaterialDefault(); 187 cubeMat.shader = ditherShader; 188 189 Matrix rotZ = MatrixRotateZ(54.7356f * DEG2RAD); 190 Matrix rotY = MatrixRotateY(45.0f * DEG2RAD); 191 Matrix baseRotation = MatrixMultiply(rotY, rotZ); 192 193 Vector3 upVector = {0.0f, 1.0f, 0.0f}; 194 195 float timeAccumulator = 0.0f; 196 197 while (!WindowShouldClose()) { 198 float dt = GetFrameTime(); 199 timeAccumulator += dt; 200 201 if (IsWindowResized()) { 202 UnloadRenderTexture(target); 203 target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight()); 204 currentScreenSize = 205 (Vector2){(float)GetScreenWidth(), (float)GetScreenHeight()}; 206 SetShaderValue(liquifyShader, locScreenSize, ¤tScreenSize, 207 SHADER_UNIFORM_VEC2); 208 } 209 210 float t1 = timeAccumulator * 0.1f; 211 float t2 = 4.0f - (timeAccumulator * 0.6f + 2.0f); 212 while (t2 < 0) 213 t2 += 400.0f; 214 215 Vector2 p1 = GetPerimeterPosition(t1); 216 Vector2 p2 = GetPerimeterPosition(t2); 217 218 SetShaderValue(liquifyShader, locCenter1, &p1, SHADER_UNIFORM_VEC2); 219 SetShaderValue(liquifyShader, locCenter2, &p2, SHADER_UNIFORM_VEC2); 220 221 float t03 = timeAccumulator * 0.05f; 222 float t042 = timeAccumulator * 0.05f; 223 float t015 = timeAccumulator * 0.05f; 224 camera.position = (Vector3){sinf(t03) * 10.0f, 0.0f, cosf(t042) * 10.0f}; 225 camera.target = 226 (Vector3){sinf(t03 + 1.0f) * 5.0f, 0.0f, cosf(t042 + 1.0f) * 5.0f}; 227 UpdateCamera(&camera, CAMERA_ORBITAL); 228 229 float camPos[3] = {camera.position.x, camera.position.y, camera.position.z}; 230 SetShaderValue(ditherShader, ditherShader.locs[SHADER_LOC_VECTOR_VIEW], 231 camPos, SHADER_UNIFORM_VEC3); 232 233 Vector2 camPos2D = {camera.position.x, camera.position.z}; 234 int count = 0; 235 int gridOffsetX = (int)(camera.position.x / SPACING); 236 int gridOffsetZ = (int)(camera.position.z / SPACING); 237 238 for (int x = -FIELD_SIZE / 2; x < FIELD_SIZE / 2; x++) { 239 int seedX = gridOffsetX + x; 240 float baseX = seedX * SPACING + (SPACING / 2); 241 242 for (int z = -FIELD_SIZE / 2; z < FIELD_SIZE / 2; z++) { 243 int seedZ = gridOffsetZ + z; 244 float baseZ = seedZ * SPACING + (SPACING / 2); 245 246 float tiltX = HASH(seedX, seedZ) * TILT_STRENGTH; 247 float tiltZ = HASH(seedZ, seedX) * TILT_STRENGTH; 248 float offsetX = HASH(seedX, seedZ) * OFFSET_STRENGTH; 249 float offsetZ = HASH(seedZ, seedX) * OFFSET_STRENGTH; 250 251 float chainAtCamY_X = baseX + (camera.position.y * tiltX) + offsetX; 252 float chainAtCamY_Z = baseZ + (camera.position.y * tiltZ) + offsetZ; 253 254 if (Vector2DistanceSqr((Vector2){chainAtCamY_X, chainAtCamY_Z}, 255 camPos2D) > RENDER_CULL_SQ) 256 continue; 257 258 Vector3 chainDir = Vector3Normalize((Vector3){tiltX, 1.0f, tiltZ}); 259 Vector3 rotationAxis = Vector3CrossProduct(upVector, chainDir); 260 float rotationAngle = acosf(Vector3DotProduct(upVector, chainDir)); 261 Matrix tiltRotation = MatrixRotate(rotationAxis, rotationAngle); 262 263 Matrix instanceMatrix = MatrixMultiply(baseRotation, tiltRotation); 264 265 for (int yIndex = -CHAIN_HEIGHT / 2; yIndex < CHAIN_HEIGHT / 2; 266 yIndex++) { 267 float yy = yIndex * VERTICAL_SPACING; 268 269 if (fabsf(yy - camera.position.y) > RENDER_CULL_DISTANCE) 270 continue; 271 272 if (count < MAX_INSTANCES) { 273 float finalX = baseX + (yy * tiltX) + offsetX; 274 float finalZ = baseZ + (yy * tiltZ) + offsetZ; 275 276 transforms[count] = instanceMatrix; 277 transforms[count].m12 = finalX; 278 transforms[count].m13 = yy; 279 transforms[count].m14 = finalZ; 280 count++; 281 } 282 } 283 } 284 } 285 286 BeginTextureMode(target); 287 ClearBackground(BLACK); 288 BeginMode3D(camera); 289 if (count > 0) { 290 DrawMeshInstanced(cubeMesh, cubeMat, transforms, count); 291 } 292 EndMode3D(); 293 EndTextureMode(); 294 295 BeginDrawing(); 296 ClearBackground(BLACK); 297 BeginShaderMode(liquifyShader); 298 DrawTexturePro( 299 target.texture, 300 (Rectangle){0, 0, (float)target.texture.width, 301 (float)-target.texture.height}, 302 (Rectangle){0, 0, (float)GetScreenWidth(), (float)GetScreenHeight()}, 303 (Vector2){0, 0}, 0.0f, WHITE); 304 EndShaderMode(); 305 EndDrawing(); 306 } 307 308 UnloadRenderTexture(target); 309 UnloadMesh(cubeMesh); 310 UnloadMaterial(cubeMat); 311 UnloadShader(ditherShader); 312 UnloadShader(liquifyShader); 313 314 CloseWindow(); 315 return 0; 316 }