BRL-CAD
liboslrend.cpp
Go to the documentation of this file.
1 /* L I B O S L R E N D . C P P
2  * BRL-CAD
3  *
4  * Copyright (c) 2011-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file osl-renderer.cpp
21  *
22  * This code represents an interface to OSL system. Through it, one can
23  * add OSL shaders and query colors, given some global parameters
24  */
25 
26 #include "liboslrend.h"
27 
28 
30 {
31 
32  shadingsys = ShadingSystem::create(&rend, NULL, &errhandler);
33 
34  ssi = (ShadingSystemImpl *)shadingsys;
35 }
36 
37 
39 {
40 
41  ssi->destroy_thread_info(handle);
42  ShadingSystem::destroy(shadingsys);
43 }
44 
45 
46 ShadingAttribStateRef
48 {
49 
50  shadingsys->ShaderGroupBegin();
51 
52  for (size_t i = 0; i < group_info.shader_layers.size(); i++) {
53 
54  ShaderInfo &sh_info = group_info.shader_layers[i];
55 
56  /* Set parameters */
57  for (size_t i = 0; i < sh_info.iparam.size(); i++)
58  shadingsys->Parameter(sh_info.iparam[i].first.c_str(), TypeDesc::TypeInt, &(sh_info.iparam[i].second));
59  for (size_t i = 0; i < sh_info.fparam.size(); i++)
60  shadingsys->Parameter(sh_info.fparam[i].first.c_str(), TypeDesc::TypeFloat, &(sh_info.fparam[i].second));
61  for (size_t i = 0; i < sh_info.cparam.size(); i++)
62  shadingsys->Parameter(sh_info.cparam[i].first.c_str(), TypeDesc::TypeColor, &(sh_info.cparam[i].second));
63  for (size_t i = 0; i < sh_info.sparam.size(); i++)
64  shadingsys->Parameter(sh_info.sparam[i].first.c_str(), TypeDesc::TypeString, &(sh_info.sparam[i].second));
65  for (size_t i = 0; i < sh_info.vparam.size(); i++) {
66  std::pair< TypeDesc, Vec3 > &vec_type = sh_info.vparam[i].second;
67  shadingsys->Parameter(sh_info.vparam[i].first.c_str(), vec_type.first, &(vec_type.second));
68  }
69  for (size_t i = 0; i < sh_info.mparam.size(); i++)
70  shadingsys->Parameter(sh_info.mparam[i].first.c_str(), TypeDesc::TypeMatrix, &(sh_info.mparam[i].second));
71 
72  if (sh_info.layername == "")
73  shadingsys->Shader("surface", sh_info.shadername.c_str(), NULL);
74  else
75  shadingsys->Shader("surface", sh_info.shadername.c_str(), sh_info.layername.c_str());
76  }
77 
78  /* Set the edges between shader layers */
79  for (size_t i = 0; i < group_info.shader_edges.size(); i++) {
80  ShaderParam &sh_param1 = group_info.shader_edges[i].first;
81  ShaderParam &sh_param2 = group_info.shader_edges[i].second;
82  shadingsys->ConnectShaders(sh_param1.layername.c_str(), sh_param1.paramname.c_str(),
83  sh_param2.layername.c_str(), sh_param2.paramname.c_str());
84 
85  }
86 
87  shadingsys->ShaderGroupEnd();
88 
89  ShadingAttribStateRef sh_ref = shadingsys->state();
90  shadingsys->clear_state();
91 
92  return sh_ref;
93 }
94 
95 
96 Color3
98 {
99  if (info->depth >= 5) {
100  return Color3(0.0f);
101  }
102 
103  fastf_t y = info->screen_y;
104 
105  unsigned short Xi[3]; /* seed for RNG */
106  Xi[0] = rand();
107  Xi[1] = rand();
108  Xi[2] = rand();
109 
110  // execute shader
111  ShaderGlobals globals;
112  const ClosureColor *closure = ExecuteShaders(globals, info);
113 
114  Color3 weight = Color3(0.0f);
115  // sample primitive from closure tree
116  const ClosurePrimitive *prim = SamplePrimitive(weight, closure, 0.5);
117 
118 // Ray-tracing (local illumination)
119 
120  if (prim) {
121  if (prim->category() == OSL::ClosurePrimitive::BSDF) {
122  // sample BSDF closure
123  BSDFClosure *bsdf = (BSDFClosure*)prim;
124  Vec3 omega_in, zero(0.0f);
125  Color3 eval;
126  float pdf = 0.0;
127 
128  ustring ulabel = bsdf->sample(globals.Ng, globals.I, zero, zero,
129  erand48(Xi), erand48(Xi),
130  omega_in, zero, zero, pdf, eval);
131 
132  if (ulabel == OSL::Labels::REFLECT)
133  info->out_ray_type |= RAY_REFLECT;
134  else if (ulabel == OSL::Labels::TRANSMIT)
135  info->out_ray_type |= RAY_TRANSMIT;
136 
137  if (pdf != 0.0f) {
138  OSLRenderer::Vec3toPoint_t(globals.P, info->out_ray.origin);
139 
140  OSLRenderer::Vec3toPoint_t(omega_in, info->out_ray.dir);
141  info->doreflection = 1;
142  return weight*eval/pdf;
143  }
144  }
145  else if (prim->category() == OSL::ClosurePrimitive::Emissive) {
146  // evaluate emissive closure
147  EmissiveClosure *emissive = (EmissiveClosure*)prim;
148  Color3 l = weight*emissive->eval(globals.Ng, globals.I);
149  return l;
150  }
151  else if (prim->category() == OSL::ClosurePrimitive::Background) {
152  // background closure just returns weight
153  return weight;
154  }
155  }
156  return Color3(0.0f);
157 }
158 
159 
160 /* Return thread specific information */
161 void*
163 {
164  return ssi->create_thread_info();
165 }
166 
167 
168 /* -----------------------------------------------
169  * Private methods
170  * ----------------------------------------------- */
171 
172 const ClosureColor * OSLRenderer::
173 ExecuteShaders(ShaderGlobals &globals, RenderInfo *info) const
174 {
175  memset(&globals, 0, sizeof(globals));
176 
177  VMOVE(globals.P, info->P);
178  VMOVE(globals.I, info->I);
179  VREVERSE(globals.I, globals.I);
180  VMOVE(globals.Ng, info->N);
181 
182  globals.N = globals.Ng;
183 
184  // u-v coordinates
185  globals.u = info->u;
186  globals.v = info->v;
187 
188  // u-v tangents
189  VMOVE(globals.dPdu, info->dPdu);
190  VMOVE(globals.dPdv, info->dPdv);
191 
192  // other
193  globals.raytype |= ((info->depth == 0) & (1 << 1));
194  globals.surfacearea = info->surfacearea;
195  globals.backfacing = (globals.Ng.dot(globals.I) < 0.0f);
196  globals.Ci = NULL;
197 
198  // execute shader
199  ShadingContext* ctx = ssi->get_context(info->thread_info);
200  ctx->execute(ShadUseSurface, *(info->shader_ref),
201  globals);
202  ssi->release_context(ctx, info->thread_info);
203 
204  return globals.Ci;
205 }
206 
207 const ClosurePrimitive * OSLRenderer::SamplePrimitive(Color3& weight, const ClosureColor *closure, float r) const {
208 
209  if (closure) {
210  const ClosurePrimitive *prim = NULL;
211  float totw = 0.0f;
212 
213  SamplePrimitiveRecurse(prim, weight, closure, Color3(1.0f), totw, r);
214  weight *= totw;
215 
216  return prim;
217  }
218  return NULL;
219 }
220 void OSLRenderer::SamplePrimitiveRecurse(const ClosurePrimitive*& r_prim, Color3& r_weight, const ClosureColor *closure,
221  const Color3& weight, float& totw, float& r) const {
222 
223  if (closure->type == ClosureColor::COMPONENT) {
224 
225  ClosureComponent *comp = (ClosureComponent*)closure;
226  ClosurePrimitive *prim = (ClosurePrimitive*)comp->data();
227  float p, w = fabsf(weight[0]) + fabsf(weight[1]) + fabsf(weight[2]);
228 
229  if (w == 0.0f)
230  return;
231 
232  totw += w;
233 
234  if (!r_prim) {
235  // no primitive was found yet, so use this
236  r_prim = prim;
237  r_weight = weight/w;
238  }
239  else {
240 
241  p = w/totw;
242 
243  if (r < p) {
244  // pick other primitive
245  r_prim = prim;
246  r_weight = weight/w;
247 
248  r = r/p;
249  }
250  else {
251  // keep existing primitive
252  r = (r + p)/(1.0f - p);
253  }
254  }
255  }
256  else if (closure->type == ClosureColor::MUL) {
257  ClosureMul *mul = (ClosureMul*)closure;
258 
259  SamplePrimitiveRecurse(r_prim, r_weight, mul->closure, mul->weight * weight, totw, r);
260  }
261  else if (closure->type == ClosureColor::ADD) {
262  ClosureAdd *add = (ClosureAdd*)closure;
263 
264  SamplePrimitiveRecurse(r_prim, r_weight, add->closureA, weight, totw, r);
265  SamplePrimitiveRecurse(r_prim, r_weight, add->closureB, weight, totw, r);
266  }
267 }
268 
269 // Local Variables:
270 // tab-width: 8
271 // mode: C++
272 // c-basic-offset: 4
273 // indent-tabs-mode: t
274 // c-file-style: "stroustrup"
275 // End:
276 // ex: shiftwidth=4 tabstop=8
point_t dir
Definition: liboslrend.h:47
void * thread_info
Definition: liboslrend.h:62
std::string paramname
Definition: liboslrend.h:106
void eval()
Definition: vm_test.cpp:79
void destroy_thread_info(void *thread_info)
std::vector< std::pair< std::string, TypeVec > > vparam
Definition: liboslrend.h:99
std::string layername
Definition: liboslrend.h:95
double add(double a, double b)
Definition: vm_test.cpp:38
fastf_t surfacearea
Definition: liboslrend.h:71
std::vector< std::pair< std::string, Matrix44 > > mparam
Definition: liboslrend.h:101
Color3 QueryColor(RenderInfo *info) const
Definition: liboslrend.cpp:97
int out_ray_type
Definition: liboslrend.h:79
point_t N
Definition: liboslrend.h:66
ShadingAttribStateRef AddShader(ShaderGroupInfo &group_info)
Definition: liboslrend.cpp:47
std::vector< ShaderEdge > shader_edges
Definition: liboslrend.h:114
static void Vec3toPoint_t(Vec3 s, point_t t)
Definition: liboslrend.h:156
point_t P
Definition: liboslrend.h:65
void * memset(void *s, int c, size_t n)
void * CreateThreadInfo()
Definition: liboslrend.cpp:162
ShadingAttribStateRef shader_ref
Definition: liboslrend.h:72
void execute(ShaderUse use, ShadingAttribState &sas, ShaderGlobals &ssg)
std::vector< ShaderInfo > shader_layers
Definition: liboslrend.h:113
std::vector< std::pair< std::string, float > > fparam
Definition: liboslrend.h:97
point_t I
Definition: liboslrend.h:67
std::string shadername
Definition: liboslrend.h:94
fastf_t u
Definition: liboslrend.h:68
ShadingContext * get_context(void *thread_info=NULL)
fastf_t v
Definition: liboslrend.h:68
fastf_t screen_y
Definition: liboslrend.h:64
std::vector< std::pair< std::string, int > > iparam
Definition: liboslrend.h:96
point_t dPdv
Definition: liboslrend.h:69
point_t dPdu
Definition: liboslrend.h:69
std::vector< std::pair< std::string, std::string > > sparam
Definition: liboslrend.h:100
std::string layername
Definition: liboslrend.h:105
Ray out_ray
Definition: liboslrend.h:80
double fastf_t
Definition: defines.h:300
void release_context(ShadingContext *sc, void *thread_info=NULL)
struct bu_list l
magic # and doubly linked list
Definition: raytrace.h:538
point_t origin
Definition: liboslrend.h:48
int doreflection
Definition: liboslrend.h:78
std::vector< std::pair< std::string, Color3 > > cparam
Definition: liboslrend.h:98