solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

ssol_draw_draft.c (5494B)


      1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2016, 2018 CNRS
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #include "ssol_c.h"
     18 #include "ssol_camera.h"
     19 #include "ssol_device_c.h"
     20 #include "ssol_draw.h"
     21 #include "ssol_material_c.h"
     22 #include "ssol_object_c.h"
     23 #include "ssol_scene_c.h"
     24 #include "ssol_shape_c.h"
     25 
     26 #include <rsys/double3.h>
     27 #include <rsys/dynamic_array_float.h>
     28 #include <rsys/float3.h>
     29 
     30 #include <star/ssp.h>
     31 
     32 #include <float.h>
     33 
     34 /*******************************************************************************
     35  * Helper functions
     36  ******************************************************************************/
     37 static void
     38 Li
     39   (struct ssol_scene* scn,
     40    struct s3d_scene_view* view,
     41    const float org[3],
     42    const float dir[3],
     43    double val[3])
     44 {
     45   const float range[2] = {0, FLT_MAX};
     46   struct ssol_surface_fragment frag;
     47   struct ray_data ray_data = RAY_DATA_NULL;
     48   struct s3d_hit hit;
     49   ASSERT(scn && view && org && dir && val);
     50 
     51   ray_data.scn = scn;
     52   ray_data.discard_virtual_materials = 1;
     53   S3D(scene_view_trace_ray(view, org, dir, range, &ray_data, &hit));
     54   if(S3D_HIT_NONE(&hit)) {
     55     d3_splat(val, 0);
     56   } else {
     57     struct ssol_instance* inst;
     58     struct ssol_material* mtl;
     59     const struct shaded_shape* sshape;
     60     size_t isshape;
     61     double o[3], wi[3];
     62     double N[3]={0};
     63     double cos_N_wi;
     64 
     65     /* Retrieve the hit shaded shape */
     66     inst = *htable_instance_find(&scn->instances_rt, &hit.prim.inst_id);
     67     isshape = *htable_shaded_shape_find
     68       (&inst->object->shaded_shapes_rt, &hit.prim.geom_id);
     69     sshape = darray_shaded_shape_cdata_get
     70       (&inst->object->shaded_shapes) + isshape;
     71 
     72     /* Retrieve and normalized the hit normal */
     73     switch(sshape->shape->type) {
     74       case SHAPE_MESH: d3_normalize(N, d3_set_f3(N, hit.normal)); break;
     75       case SHAPE_PUNCHED: d3_normalize(N, ray_data.N); break;
     76         break;
     77       default: FATAL("Unreachable code"); break;
     78     }
     79 
     80     d3_set_f3(o, org);
     81     d3_set_f3(wi, dir);
     82     d3_normalize(wi, wi);
     83     if(d3_dot(N, wi) < 0) {
     84       mtl = sshape->mtl_front;
     85     } else {
     86       mtl = sshape->mtl_back;
     87       d3_minus(N, N);
     88     }
     89 
     90     surface_fragment_setup(&frag, o, wi, N, &hit.prim, hit.uv);
     91     material_shade_normal(mtl, &frag, 1/*TODO wavelength*/, N);
     92 
     93     ASSERT(d3_is_normalized(N));
     94     cos_N_wi = d3_dot(N, d3_minus(wi, wi));
     95     d3_splat(val, MMAX(cos_N_wi, 0));
     96   }
     97 }
     98 
     99 static void
    100 draw_pixel
    101   (struct ssol_scene* scn,
    102    const struct ssol_camera* cam,
    103    struct s3d_scene_view* view,
    104    const int ithread,
    105    const size_t pix_coords[2], /* Image space pixel coordinates */
    106    const float pix_sz[2], /* Normalized pixel size */
    107    const size_t nsamples,
    108    double pixel[3],
    109    void* data)
    110 {
    111   struct darray_float* samples = data;
    112   float samp[2];
    113   float ray_org[3], ray_dir[3];
    114   double sum[3] = {0, 0, 0};
    115   size_t i;
    116   ASSERT(scn && cam && view && pix_coords && pix_sz && nsamples && pixel && data);
    117   (void)ithread;
    118 
    119   FOR_EACH(i, 0, nsamples) {
    120     double weight[3];
    121     const float* r = darray_float_cdata_get(samples) + i*2;
    122 
    123     /* Generate a sample into the pixel */
    124     samp[0] = ((float)pix_coords[0] + r[0]) * pix_sz[0];
    125     samp[1] = ((float)pix_coords[1] + r[1]) * pix_sz[1];
    126 
    127     /* Generate a ray starting from the pinhole camera and passing through the
    128      * pixel sample */
    129     camera_ray(cam, samp, ray_org, ray_dir);
    130 
    131     /* Compute the radiance arriving through the sampled camera ray */
    132     Li(scn, view, ray_org, ray_dir, weight);
    133     d3_add(sum, sum, weight);
    134   }
    135   d3_divd(pixel, sum, (double)nsamples);
    136 }
    137 
    138 
    139 /*******************************************************************************
    140  * Exported function
    141  ******************************************************************************/
    142 res_T
    143 ssol_draw_draft
    144   (struct ssol_scene* scn,
    145    struct ssol_camera* cam,
    146    const size_t width,
    147    const size_t height,
    148    const size_t spp,
    149    ssol_write_pixels_T writer,
    150    void* data)
    151 {
    152   struct darray_float samples;
    153   struct ssp_rng* rng = NULL;
    154   size_t i;
    155   res_T res = RES_OK;
    156 
    157   if(!scn || !spp) return RES_BAD_ARG;
    158 
    159   darray_float_init(scn->dev->allocator, &samples);
    160 
    161   res = scene_check(scn, FUNC_NAME);
    162   if(res != RES_OK) goto error;
    163 
    164   res = darray_float_reserve(&samples, spp * 2/*#dimensions*/);
    165   if(res != RES_OK) goto error;
    166 
    167   res = ssp_rng_create(scn->dev->allocator, SSP_RNG_THREEFRY, &rng);
    168   if(res != RES_OK) goto error;
    169 
    170   /* Generate the pixel samples */
    171   FOR_EACH(i, 0, spp) {
    172     const float x = ssp_rng_canonical_float(rng);
    173     const float y = ssp_rng_canonical_float(rng);
    174     darray_float_push_back(&samples, &x);
    175     darray_float_push_back(&samples, &y);
    176   }
    177 
    178   res = draw(scn, cam, width, height, spp, writer, data, draw_pixel, &samples);
    179   if(res != RES_OK) goto error;
    180 
    181 exit:
    182   darray_float_release(&samples);
    183   if(rng) SSP(rng_ref_put(rng));
    184   return res;
    185 error:
    186   goto exit;
    187 }
    188