1 /* 2 Copyright (c) 2005-2021 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 /* 18 The original source for this example is 19 Copyright (c) 1994-2008 John E. Stone 20 All rights reserved. 21 22 Redistribution and use in source and binary forms, with or without 23 modification, are permitted provided that the following conditions 24 are met: 25 1. Redistributions of source code must retain the above copyright 26 notice, this list of conditions and the following disclaimer. 27 2. Redistributions in binary form must reproduce the above copyright 28 notice, this list of conditions and the following disclaimer in the 29 documentation and/or other materials provided with the distribution. 30 3. The name of the author may not be used to endorse or promote products 31 derived from this software without specific prior written permission. 32 33 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 34 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 37 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43 SUCH DAMAGE. 44 */ 45 46 /* 47 * texture.cpp - This file contains functions for implementing textures. 48 */ 49 50 #include "machine.hpp" 51 #include "types.hpp" 52 #include "macros.hpp" 53 #include "texture.hpp" 54 #include "coordsys.hpp" 55 #include "imap.hpp" 56 #include "vector.hpp" 57 #include "box.hpp" 58 59 /* plain vanilla texture solely based on object color */ 60 color standard_texture(vector *hit, texture *tex, ray *ry) { 61 return tex->col; 62 } 63 64 /* cylindrical image map */ 65 color image_cyl_texture(vector *hit, texture *tex, ray *ry) { 66 vector rh; 67 flt u, v; 68 69 rh.x = hit->x - tex->ctr.x; 70 rh.z = hit->y - tex->ctr.y; 71 rh.y = hit->z - tex->ctr.z; 72 73 xyztocyl(rh, 1.0, &u, &v); 74 75 u = u * tex->scale.x; 76 u = u + tex->rot.x; 77 u = fmod(u, 1.0); 78 if (u < 0.0) 79 u += 1.0; 80 81 v = v * tex->scale.y; 82 v = v + tex->rot.y; 83 v = fmod(v, 1.0); 84 if (v < 0.0) 85 v += 1.0; 86 87 return ImageMap((rawimage *)tex->img, u, v); 88 } 89 90 /* spherical image map */ 91 color image_sphere_texture(vector *hit, texture *tex, ray *ry) { 92 vector rh; 93 flt u, v; 94 95 rh.x = hit->x - tex->ctr.x; 96 rh.y = hit->y - tex->ctr.y; 97 rh.z = hit->z - tex->ctr.z; 98 99 xyztospr(rh, &u, &v); 100 101 u = u * tex->scale.x; 102 u = u + tex->rot.x; 103 u = fmod(u, 1.0); 104 if (u < 0.0) 105 u += 1.0; 106 107 v = v * tex->scale.y; 108 v = v + tex->rot.y; 109 v = fmod(v, 1.0); 110 if (v < 0.0) 111 v += 1.0; 112 113 return ImageMap((rawimage *)tex->img, u, v); 114 } 115 116 /* planar image map */ 117 color image_plane_texture(vector *hit, texture *tex, ray *ry) { 118 vector pnt; 119 flt u, v; 120 121 pnt.x = hit->x - tex->ctr.x; 122 pnt.y = hit->y - tex->ctr.y; 123 pnt.z = hit->z - tex->ctr.z; 124 125 VDOT(u, tex->uaxs, pnt); 126 /* VDOT(len, tex->uaxs, tex->uaxs); 127 u = u / sqrt(len); */ 128 129 VDOT(v, tex->vaxs, pnt); 130 /* VDOT(len, tex->vaxs, tex->vaxs); 131 v = v / sqrt(len); */ 132 133 u = u * tex->scale.x; 134 u = u + tex->rot.x; 135 u = fmod(u, 1.0); 136 if (u < 0.0) 137 u += 1.0; 138 139 v = v * tex->scale.y; 140 v = v + tex->rot.y; 141 v = fmod(v, 1.0); 142 if (v < 0.0) 143 v += 1.0; 144 145 return ImageMap((rawimage *)tex->img, u, v); 146 } 147 148 color grit_texture(vector *hit, texture *tex, ray *ry) { 149 int rnum; 150 flt fnum; 151 color col; 152 153 rnum = rand() % 4096; 154 fnum = (rnum / 4096.0 * 0.2) + 0.8; 155 156 col.r = tex->col.r * fnum; 157 col.g = tex->col.g * fnum; 158 col.b = tex->col.b * fnum; 159 160 return col; 161 } 162 163 color checker_texture(vector *hit, texture *tex, ray *ry) { 164 long x, y, z; 165 flt xh, yh, zh; 166 color col; 167 168 xh = hit->x - tex->ctr.x; 169 x = (long)((fabs(xh) * 3) + 0.5); 170 x = x % 2; 171 yh = hit->y - tex->ctr.y; 172 y = (long)((fabs(yh) * 3) + 0.5); 173 y = y % 2; 174 zh = hit->z - tex->ctr.z; 175 z = (long)((fabs(zh) * 3) + 0.5); 176 z = z % 2; 177 178 if (((x + y + z) % 2) == 1) { 179 col.r = 1.0; 180 col.g = 0.2; 181 col.b = 0.0; 182 } 183 else { 184 col.r = 0.0; 185 col.g = 0.2; 186 col.b = 1.0; 187 } 188 189 return col; 190 } 191 192 color cyl_checker_texture(vector *hit, texture *tex, ray *ry) { 193 long x, y; 194 vector rh; 195 flt u, v; 196 color col; 197 198 rh.x = hit->x - tex->ctr.x; 199 rh.y = hit->y - tex->ctr.y; 200 rh.z = hit->z - tex->ctr.z; 201 202 xyztocyl(rh, 1.0, &u, &v); 203 204 x = (long)(fabs(u) * 18.0); 205 x = x % 2; 206 y = (long)(fabs(v) * 10.0); 207 y = y % 2; 208 209 if (((x + y) % 2) == 1) { 210 col.r = 1.0; 211 col.g = 0.2; 212 col.b = 0.0; 213 } 214 else { 215 col.r = 0.0; 216 col.g = 0.2; 217 col.b = 1.0; 218 } 219 220 return col; 221 } 222 223 color wood_texture(vector *hit, texture *tex, ray *ry) { 224 flt radius, angle; 225 int grain; 226 color col; 227 flt x, y, z; 228 229 x = (hit->x - tex->ctr.x) * 1000; 230 y = (hit->y - tex->ctr.y) * 1000; 231 z = (hit->z - tex->ctr.z) * 1000; 232 233 radius = sqrt(x * x + z * z); 234 if (z == 0.0) 235 angle = 3.1415926 / 2.0; 236 else 237 angle = atan(x / z); 238 239 radius = radius + 3.0 * sin(20 * angle + y / 150.0); 240 grain = ((int)(radius + 0.5)) % 60; 241 if (grain < 40) { 242 col.r = 0.8; 243 col.g = 1.0; 244 col.b = 0.2; 245 } 246 else { 247 col.r = 0.0; 248 col.g = 0.0; 249 col.b = 0.0; 250 } 251 252 return col; 253 } 254 255 #define NMAX 28 256 short int NoiseMatrix[NMAX][NMAX][NMAX]; 257 258 void InitNoise(void) { 259 byte_t x, y, z, i, j, k; 260 261 for (x = 0; x < NMAX; x++) { 262 for (y = 0; y < NMAX; y++) { 263 for (z = 0; z < NMAX; z++) { 264 NoiseMatrix[x][y][z] = rand() % 12000; 265 266 if (x == NMAX - 1) 267 i = 0; 268 else 269 i = x; 270 271 if (y == NMAX - 1) 272 j = 0; 273 else 274 j = y; 275 276 if (z == NMAX - 1) 277 k = 0; 278 else 279 k = z; 280 281 NoiseMatrix[x][y][z] = NoiseMatrix[i][j][k]; 282 } 283 } 284 } 285 } 286 287 int Noise(flt x, flt y, flt z) { 288 byte_t ix, iy, iz; 289 flt ox, oy, oz; 290 int p000, p001, p010, p011; 291 int p100, p101, p110, p111; 292 int p00, p01, p10, p11; 293 int p0, p1; 294 int d00, d01, d10, d11; 295 int d0, d1, d; 296 297 x = fabs(x); 298 y = fabs(y); 299 z = fabs(z); 300 301 ix = ((int)x) % (NMAX - 1); 302 iy = ((int)y) % (NMAX - 1); 303 iz = ((int)z) % (NMAX - 1); 304 305 ox = (x - ((int)x)); 306 oy = (y - ((int)y)); 307 oz = (z - ((int)z)); 308 309 p000 = NoiseMatrix[ix][iy][iz]; 310 p001 = NoiseMatrix[ix][iy][iz + 1]; 311 p010 = NoiseMatrix[ix][iy + 1][iz]; 312 p011 = NoiseMatrix[ix][iy + 1][iz + 1]; 313 p100 = NoiseMatrix[ix + 1][iy][iz]; 314 p101 = NoiseMatrix[ix + 1][iy][iz + 1]; 315 p110 = NoiseMatrix[ix + 1][iy + 1][iz]; 316 p111 = NoiseMatrix[ix + 1][iy + 1][iz + 1]; 317 318 d00 = p100 - p000; 319 d01 = p101 - p001; 320 d10 = p110 - p010; 321 d11 = p111 - p011; 322 323 p00 = (int)((int)d00 * ox) + p000; 324 p01 = (int)((int)d01 * ox) + p001; 325 p10 = (int)((int)d10 * ox) + p010; 326 p11 = (int)((int)d11 * ox) + p011; 327 d0 = p10 - p00; 328 d1 = p11 - p01; 329 p0 = (int)((int)d0 * oy) + p00; 330 p1 = (int)((int)d1 * oy) + p01; 331 d = p1 - p0; 332 333 return (int)((int)d * oz) + p0; 334 } 335 336 color marble_texture(vector *hit, texture *tex, ray *ry) { 337 flt i, d; 338 flt x, y, z; 339 color col; 340 341 x = hit->x; 342 y = hit->y; 343 z = hit->z; 344 345 x = x * 1.0; 346 347 d = x + 0.0006 * Noise(x, (y * 1.0), (z * 1.0)); 348 d = d * (((int)d) % 25); 349 i = 0.0 + 0.10 * fabs(d - 10.0 - 20.0 * ((int)d * 0.05)); 350 if (i > 1.0) 351 i = 1.0; 352 if (i < 0.0) 353 i = 0.0; 354 355 /* 356 col.r=i * tex->col.r; 357 col.g=i * tex->col.g; 358 col.b=i * tex->col.b; 359 */ 360 361 col.r = (1.0 + sin(i * 6.28)) / 2.0; 362 col.g = (1.0 + sin(i * 16.28)) / 2.0; 363 col.b = (1.0 + cos(i * 30.28)) / 2.0; 364 365 return col; 366 } 367 368 color gnoise_texture(vector *hit, texture *tex, ray *ry) { 369 color col; 370 flt f; 371 372 f = Noise((hit->x - tex->ctr.x), (hit->y - tex->ctr.y), (hit->z - tex->ctr.z)); 373 374 if (f < 0.01) 375 f = 0.01; 376 if (f > 1.0) 377 f = 1.0; 378 379 col.r = tex->col.r * f; 380 col.g = tex->col.g * f; 381 col.b = tex->col.b * f; 382 383 return col; 384 } 385 386 void InitTextures(void) { 387 InitNoise(); 388 ResetImages(); 389 } 390