bsdf.glsl 17.3 KB
Newer Older
1
2
3
#ifndef __BSDF_DIFFUSE_GLH
#define __BDSF_DIFFUSE_GLH

Johannes Braun's avatar
Johannes Braun committed
4
5
6
7
8
#include <raytracer/basic_structs.glsl>
#include <raytracer/random.glsl>
#include <raytracer/utilities.glsl>
#include <raytracer/properties/ray_transform.glsl>
#include <raytracer/properties/fresnel.glsl>
Johannes Braun's avatar
Johannes Braun committed
9
10

#include <screenshader/gbuffer/cook_torrance.glsl>
11
#include <raytracer/properties/ggx.glsl>
Johannes Braun's avatar
Johannes Braun committed
12

13
14
15
16
17
18
// BSDF IDs
const uint eDiffuse = 0;
const uint eReflect = 1;
const uint eTransmit = 2;
const uint eEmit = 3;

Johannes Braun's avatar
Johannes Braun committed
19
20
21
22
23
24
25
26
27
struct BSDFResult
{
	// A newly generated ray for shading
	Ray generated_ray;

	// How the color coming from the generated ray direction will be tinted
	vec3 radiance;

	// How the incoming light will be tinted
28
	vec3 evaluation;
Johannes Braun's avatar
Johannes Braun committed
29
30

	// The probability of the generated ray (result of the probability distribution function)
31
	float probability_density;
Johannes Braun's avatar
Johannes Braun committed
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

	// For effect purposes: set a dedicated id for the type of effect achieved
	uint bsdf_id;
};

struct SampledMaterial
{
	vec4 diffuse;
	vec4 specular;
	vec4 transparent;
	vec4 emissive;
	vec4 ambient;

	float roughness;	// 0..1
	float metallic;		// 0..1
	float ior;				// 0..n
};

unknown's avatar
unknown committed
50
vec3 reflectedDirection(vec3 local_hemi_sample, vec3 normal, vec3 reflected, float roughness)
Johannes Braun's avatar
Johannes Braun committed
51
{
unknown's avatar
unknown committed
52
	return normalize(localToWorld(local_hemi_sample, normal, reflected));
Johannes Braun's avatar
Johannes Braun committed
53
54
}

55
SampledMaterial getMaterialParameters(const in Material material, const in Vertex vertex)
Johannes Braun's avatar
Johannes Braun committed
56
57
58
59
60
61
62
63
64
65
66
{
	SampledMaterial sampled_material;
	sampled_material.diffuse = material.getDiffuse(vertex.texcoord);
	sampled_material.specular = material.getSpecular(vertex.texcoord);
	sampled_material.transparent = material.getTransparent(vertex.texcoord);
	sampled_material.emissive = material.getEmissive(vertex.texcoord);
	sampled_material.ambient = material.getAmbient(vertex.texcoord);

	sampled_material.roughness = material.getRoughness();
	sampled_material.metallic = clamp((sampled_material.specular.r + sampled_material.specular.g + sampled_material.specular.b )/3, 0, 1);
	sampled_material.ior = 1.56f;//material.ior;
67
68
	return sampled_material;
}
Johannes Braun's avatar
Johannes Braun committed
69

70
71
72
BSDFResult computeBSDF(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in)
{
	const SampledMaterial sampled_material = material.getMaterialParameters(vertex);
73
74

	// Importance sampling: compute an importance sample {phi, theta} and generate a local (z-up) microsurface normal, as well as an according normal distribution
75
	HemisphereSample hemisphere_sample = ggxSample(random, sampled_material.roughness);
Johannes Braun's avatar
Johannes Braun committed
76

77
	// inverse incoming direction
78
	vec3 incoming = normalize(-ray_in.direction);
Johannes Braun's avatar
Johannes Braun committed
79

80
81
82
83
84
85
86
	// Turn around normal if looking at it from the backside
	vec3 normal = faceforward(vertex.normal.xyz, -incoming, vertex.normal.xyz);

	// Transform the computed local microsurface normal to world space along the hit normal
	vec3 micro_normal = normalize(toWorld(hemisphere_sample.micro_normal, normal));

	// Now we can generate a direction of the ray being reflected at the microsurface normal
87
	vec3 outgoing = normalize(2 * clamp(dot(incoming, micro_normal), 0, 1) * micro_normal - incoming);
Johannes Braun's avatar
Johannes Braun committed
88

89
90
91
92
93
	// Compute geometric attenuation via GGX
	float geometry = ggxGeometry(incoming, outgoing, normal, micro_normal, sampled_material.roughness);

	// TODO: what exactly is causing the slight offset in color on metallic smooth surfaces?
	float arbitrary_correction_factor = mix(1.f, 0.1f, sampled_material.metallic * (1-sampled_material.roughness));
Johannes Braun's avatar
Johannes Braun committed
94

95
96
97
98
99
	// Schlick's fresnel approximation with the material's normal response
	float normal_response = arbitrary_correction_factor * normalResponse(sampled_material.ior, sampled_material.metallic);
	float fresnel = arbitrary_correction_factor * fresnelSchlick(clamp(dot(incoming, micro_normal), 0, 1), normal_response);

	// Reflections of metallic materials are tinted with the material base color.
100
	vec3 fresnel_tint = fresnelTint(fresnel, sampled_material.metallic, sampled_material.diffuse.rgb);
Johannes Braun's avatar
Johannes Braun committed
101

102
103
	float n_dot_in = clamp(dot(normal, incoming), 0, 1);
	float n_dot_out = clamp(dot(normal, outgoing), 0, 1);
104
	float m_dot_out = clamp(dot(micro_normal, outgoing), 0, 1);
Johannes Braun's avatar
Johannes Braun committed
105

106
	// In this implementation, it is defined that the importance sample generated is cos(theta) instead of the usual approach of only theta.
107
	float cos_theta = hemisphere_sample.importance.y;
Johannes Braun's avatar
Johannes Braun committed
108

109
110
111
112
113
114
115
116
	// Compute the microsurface normal probability and with that the final probability density function
	// Clamp up denominator to not divide by zero.
	float jacobian = 1 / clamp(4 * m_dot_out, 0.001f, 1);
	float propability_m = hemisphere_sample.distribution * cos_theta;
	float pdf = propability_m * jacobian;

	// Same here... clamp up denominator to not divide by zero
	float brdf_denominator = clamp((4 * n_dot_in * n_dot_out), 0.001f, 1.f);
Johannes Braun's avatar
Johannes Braun committed
117

118
119
	// Finally, build the brdf
	vec3 brdf = fresnel_tint * geometry * hemisphere_sample.distribution / brdf_denominator;
Johannes Braun's avatar
Johannes Braun committed
120
121
122


	BSDFResult result;
123
	//Use the pixel coordinates of the incoming ray.
Johannes Braun's avatar
Johannes Braun committed
124
	result.generated_ray = ray_in;
125

126
127
	// russian roulette via K_s = fresnel => K_d = 1-fresnel
	if(sampled_material.metallic == 1 || fresnel > random.x)
128
	{
129
		// Use as brdf sample
130
131
		result.generated_ray.direction = outgoing;
		result.radiance = brdf;
132
133
134
		result.probability_density = pdf;
		result.evaluation = vec3(0); // No diffuse if reflecting
		result.bsdf_id = eReflect;
135
136
137
	}
	else
	{
138
139
140
		// Sample lambertian diffuse
		result.evaluation = (1-fresnel)*(1-sampled_material.metallic)*sampled_material.diffuse.rgb * ONE_OVER_PI;
		result.generated_ray.direction = normalize(toWorld(randCosineHemisphere(random.x, random.y), normal));
141
		result.probability_density = abs(dot(vec4(result.generated_ray.direction, 0), vertex.normal)) * ONE_OVER_PI;
142
143
		result.radiance = (1-fresnel)*(1-sampled_material.metallic)*sampled_material.diffuse.rgb * ONE_OVER_PI;
		result.bsdf_id = eDiffuse;
144
145
	}

146
147
	// offset by newly generated direction
	result.generated_ray.origin = vertex.position.xyz + 1e-8f * result.generated_ray.direction;
Johannes Braun's avatar
Johannes Braun committed
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
	return result;
}














164

165
166


unknown's avatar
unknown committed
167
168
169
subroutine vec3 bsdfSampler(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id);

subroutine(bsdfSampler)
unknown's avatar
unknown committed
170
vec3 sampleDiffuse(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
171
172
173
174
175
176
177
{
	bool entering = dot(-ray_in.direction.xyz, vertex.normal.xyz) > 0.f;
	vec3 hemi = randCosineHemisphere(random.x, random.y);

	ray_out.direction.xyz = normalize(localToWorldNormal(entering ? hemi : -hemi, vertex.normal.xyz));
	pdf = abs(dot(vec4(ray_out.direction, 0), vertex.normal)) * ONE_OVER_PI;

unknown's avatar
unknown committed
178
	bsdf_id = 0;
Johannes Braun's avatar
Johannes Braun committed
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
	if (pdf == 0.f)
	{
		return vec3(0.f);
	}

	ray_out.origin = vertex.position.xyz + 1e-5 * -ray_in.direction;

	vec3 diffuse = material.getDiffuse(vertex.texcoord).xyz;

	light_influence = diffuse * ONE_OVER_PI;

	return diffuse * ONE_OVER_PI;
}

unknown's avatar
unknown committed
194
subroutine(bsdfSampler)
unknown's avatar
unknown committed
195
vec3 sampleTranslucent(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
196
197
198
199
200
201
202
203
{
	bool entering = dot(-ray_in.direction, vertex.normal.xyz) > 0.f;
	vec3 hemi = randCosineHemisphere(random.x, random.y);

	ray_out.direction.xyz =localToWorldNormal(hemi, (entering ? -1 : 1) * vertex.normal.xyz);
	pdf = abs(dot(ray_out.direction, vertex.normal.xyz)) * ONE_OVER_PI;

	ray_out.origin = vertex.position.xyz + 1e-5f * ray_in.direction;
Johannes Braun's avatar
Johannes Braun committed
204

unknown's avatar
unknown committed
205
	bsdf_id = 1;
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222

	if (pdf == 0.f)
	{
		return vec3(0.f);
	}

	vec3 diffuse = material.getDiffuse(vertex.texcoord).xyz;

	if(!entering){
		diffuse = (diffuse + material.getSpecular(vertex.texcoord).xyz) / 2.f;
	}

	light_influence = diffuse * ONE_OVER_PI;

	return diffuse * ONE_OVER_PI;
}

unknown's avatar
unknown committed
223
subroutine(bsdfSampler)
unknown's avatar
unknown committed
224
vec3 sampleGlass(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
{
	bool entering = dot(-ray_in.direction, vertex.normal.xyz) > 0.f;
	float eta_i = entering ? 1.f : material.ior;
	float eta_t = entering ? material.ior : 1.f;
	float fresnel = dialectricFresnel(abs(dot(-ray_in.direction, vertex.normal.xyz)), eta_i, eta_t);

	//refract ray.
	ray_out.direction = refract(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz), eta_i / eta_t);

	light_influence = vec3(0);
	vec3 diffuse = material.getDiffuse(vertex.texcoord).xyz;

	// Choose whether to sample refractive or reflective BSDF
	if ((ray_out.direction.xyz != vec3(0)) && (random.x > fresnel) && (!isnan(ray_out.direction.x)))
	{
		ray_out.origin = vertex.position.xyz + 1e-5 * ray_out.direction;
		pdf = 1.0f - fresnel;
		vec3 ft = diffuse*material.getTransparent(vertex.texcoord).rgb * (1.0f - fresnel);
		ft *= ( eta_i * eta_i ) / ( eta_t * eta_t );
Johannes Braun's avatar
Johannes Braun committed
244
245


unknown's avatar
unknown committed
246
		bsdf_id = 3;
Johannes Braun's avatar
Johannes Braun committed
247

248
249
		return ft / abs(dot(ray_out.direction, vertex.normal.xyz));
	}
unknown's avatar
unknown committed
250
	bsdf_id = 2;
251
252
253
254
255
256
	ray_out.direction = reflect(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz));
	ray_out.origin = vertex.position.xyz + 1e-5 * ray_out.direction;
	pdf = fresnel;
	return fresnel * material.getSpecular(vertex.texcoord).rgb / abs(dot(ray_out.direction, vertex.normal.xyz));
}

unknown's avatar
unknown committed
257
subroutine(bsdfSampler)
unknown's avatar
unknown committed
258
vec3 sampleRoughGlass(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
{
	//Needed parameters for refraction and reflection
	bool entering = dot(-ray_in.direction, vertex.normal.xyz) > 0.f;
	float eta_i = entering ? 1.f : material.ior;
	float eta_t = entering ? material.ior : 1.f;
	float fresnel = dialectricFresnel(abs(dot(-ray_in.direction, vertex.normal.xyz)), eta_i, eta_t);

	float roughness = material.getRoughness();
	vec3 diffuse = material.getDiffuse(vertex.texcoord).xyz;

	light_influence = mix(vec3(0), diffuse * ONE_OVER_PI, roughness);

	//refract ray.
	vec3 refracted = refract(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz), eta_i / eta_t).xyz;

	// Choose whether to sample refractive or reflective BSDF
	if ((refracted != vec3(0)) && (random.x > fresnel) && (!isnan(refracted.x)))
	{
		float rad = radians(180.0f - (1.0f - roughness) * 180.0f);
		vec3 sampledPoint = randAngle(random.x, random.y, rad);

		ray_out.direction.xyz = localToWorldNormal(sampledPoint, refracted);

		if (dot(ray_out.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)) > 0.0f)
		{
			ray_out.direction.xyz = localToWorldNormal(sampledPoint * vec3(-1, -1, 1), refracted);
		}

		pdf = mix(1.0f - fresnel, abs(dot(ray_out.direction, vertex.normal.xyz)) * ONE_OVER_PI, roughness);
		vec3 ft = diffuse*material.getTransparent(vertex.texcoord).rgb * (1.0f - fresnel);
Johannes Braun's avatar
Johannes Braun committed
289

290
		ft *= ( eta_i * eta_i ) / ( eta_t * eta_t );
Johannes Braun's avatar
Johannes Braun committed
291

unknown's avatar
unknown committed
292
		bsdf_id = 3;
Johannes Braun's avatar
Johannes Braun committed
293

294
295
296
297
298
299
300
301
302
303
304
305
306
		ray_out.origin = vertex.position.xyz + 1e-5 * ray_out.direction;
		return mix(ft / abs(dot(ray_out.direction, vertex.normal.xyz)), diffuse * ONE_OVER_PI, roughness);
	}
	float rad = radians(180.0f - (1.0f - roughness) * 180.0f);
	vec3 reflected = reflect(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)).xyz;
	vec3 sampledPoint = randAngle(random.x, random.y, rad);

	ray_out.direction.xyz = localToWorldNormal(sampledPoint, reflected);

	if (dot(ray_out.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)) < 0.0f)
	{
		ray_out.direction.xyz = localToWorldNormal(sampledPoint * vec3(-1, -1, 1), reflected);
	}
unknown's avatar
unknown committed
307
	bsdf_id = 2;
Johannes Braun's avatar
Johannes Braun committed
308

309
310
311
312
313
	pdf = mix(fresnel, abs(dot(ray_out.direction, vertex.normal.xyz)) * ONE_OVER_PI, roughness);
	ray_out.origin = vertex.position.xyz + 1e-5 * ray_out.direction;
	return mix(fresnel * material.getSpecular(vertex.texcoord).rgb / abs(dot(ray_out.direction, vertex.normal.xyz)), diffuse * ONE_OVER_PI, roughness);
}

unknown's avatar
unknown committed
314
subroutine(bsdfSampler)
unknown's avatar
unknown committed
315
vec3 sampleTransparent(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
316
317
318
319
320
{
	//refract ray.
	ray_out.direction = ray_in.direction;
	ray_out.origin = vertex.position.xyz + 1e-5 * ray_out.direction;
	pdf = 1;
Johannes Braun's avatar
Johannes Braun committed
321

unknown's avatar
unknown committed
322
	bsdf_id = 4;
323
324
325
326
327

	light_influence = vec3(0);
	return material.getTransparent(vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal.xyz));
}

unknown's avatar
unknown committed
328
subroutine(bsdfSampler)
unknown's avatar
unknown committed
329
vec3 sampleMirror(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
330
331
332
333
{
	pdf = 1.f;
	ray_out.direction = reflect(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz));
	light_influence = vec3(0);
unknown's avatar
unknown committed
334
	bsdf_id = 2;
335
336
337
338
339

	ray_out.origin = vertex.position.xyz + 1e-5 * ray_out.direction;
	return material.getSpecular(vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal.xyz));
}

unknown's avatar
unknown committed
340
subroutine(bsdfSampler)
unknown's avatar
unknown committed
341
vec3 sampleGlossy(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
342
343
344
345
346
347
348
349
350
351
352
{
	float roughness = material.getRoughness();
	float rad = radians(180.0f - (1.0f - roughness) * 180.0f);
	vec3 reflected = normalize(reflect(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)).xyz);
	vec3 sampledPoint = normalize(randAngle(random.x, random.y, rad));

	vec3 diffuse = material.getDiffuse(vertex.texcoord).xyz;
	light_influence = roughness * diffuse * ONE_OVER_PI;

	ray_out.direction.xyz = normalize(localToWorldNormal(sampledPoint, reflected));

unknown's avatar
unknown committed
353
	bsdf_id = 2;
Johannes Braun's avatar
Johannes Braun committed
354

355
356
357
358
359
360
361
362
363
364
365
	if (dot(ray_out.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)) < 0.0f)
	{
		ray_out.direction.xyz = normalize(localToWorldNormal(sampledPoint * vec3(-1, -1, 1), reflected));
	}
	ray_out.origin = vertex.position.xyz + 1e-5 * ray_out.direction;

	pdf = 1.f - roughness * abs(dot(ray_out.direction, vertex.normal.xyz)) * ONE_OVER_PI;

	return mix(diffuse*material.getSpecular(vertex.texcoord).xyz / abs(dot(ray_out.direction, vertex.normal.xyz)), diffuse * ONE_OVER_PI, roughness);
}

unknown's avatar
unknown committed
366
subroutine(bsdfSampler)
unknown's avatar
unknown committed
367
vec3 sampleEmissive(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
368
{
unknown's avatar
unknown committed
369
	bsdf_id = 5;
370
371
372
373
374
375
376
377
	pdf = 1.f;
	ray_out.direction = vec3(0);
	vec3 diffuse = material.getDiffuse(vertex.texcoord).xyz;
	light_influence = diffuse*material.getEmissive(vertex.texcoord).xyz;
	ray_out.origin = vertex.position.xyz + 1e-5 * ray_out.direction;
	return vec3(0);
}

378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
// subroutine(bsdfSampler)
// vec3 sampleGGX(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
// {
// 		float roughness = 1-(material.specular_exponent / 100.f);
// 		bool entering = dot(-ray_in.direction.xyz, vertex.normal.xyz) > 0.f;
// 		vec3 hemi = randCosineHemisphere(random.x, random.y);
// 		hemi.xy *= roughness;
// 		vec3 reflected = normalize(reflect(ray_in.direction, faceforward(vertex.normal.xyz, ray_in.direction, vertex.normal.xyz)).xyz);
//
// 		ray_out.origin = vertex.position.xyz + 1e-5 * -ray_in.direction;
// 		ray_out.direction.xyz = normalize(localToWorldNormal(entering ? hemi : -hemi, reflected.xyz));
//
// 		vec3 half_view = ggxHalfView(ray_out.direction.xyz, -ray_in.direction.xyz);
//
// 		vec3 diffuse_color = material.getDiffuse(vertex.texcoord).xyz;
// 		vec3 specular_color = material.getDiffuse(vertex.texcoord).xyz;
//
// 		bsdf_id = 0;
// 		float metallic = 0.f;
//
// 		float cosT = clamp(dot(ray_out.direction.xyz, vertex.normal.xyz), 0, 1);
// 		float sinT = sqrt(1 - cosT * cosT);
//
// 		vec3 fresnel = fresnelSchlick(dot(-ray_in.direction.xyz, half_view), normalResponse(diffuse_color, material.ior, metallic));
// 		float normal_dot_view = dot(vertex.normal.xyz, ray_in.direction.xyz);
// 		float geometry = ggxPartialGeometry(-ray_in.direction.xyz, vertex.normal.xyz, half_view, roughness)
// 			* ggxPartialGeometry(ray_out.direction.xyz, vertex.normal.xyz, half_view, roughness);
//
// 		float denominator = clamp(4 * (normal_dot_view * dot(half_view, vertex.normal.xyz)) + 0.05f, 0, 1);
// 		pdf = ggxDistribution(vertex.normal.xyz, half_view, roughness);
//
// 		vec3 specular_factor = fresnel;
// 		vec3 diffuse_factor = (1-specular_factor)*(1-metallic);
//
// 		light_influence = diffuse_factor * diffuse_color * ONE_OVER_PI;
//
// 		return diffuse_factor * diffuse_color * ONE_OVER_PI + geometry * fresnel * sinT / denominator;
// }
Johannes Braun's avatar
Johannes Braun committed
416

417
subroutine uniform bsdfSampler u_bsdf_sample[8];
418

unknown's avatar
unknown committed
419
vec3 sampleBSDF(const in Material material, const in vec2 random, const in Vertex vertex, const in Ray ray_in, inout Ray ray_out, out vec3 light_influence, out float pdf, out uint bsdf_id)
420
421
422
423
424
{
	//Kind of crude but also kind of well functional bsdf selector.
	ray_out.px = ray_in.px;
	ray_out.py = ray_in.py;
	bool rough = material.specular_exponent < 99;
unknown's avatar
unknown committed
425
426
	bool transparent = length(material.getTransparent(vertex.texcoord).xyz) >= 0.1;
	bool emits = length(material.getEmissive(vertex.texcoord).xyz) >= 0.01;
427

unknown's avatar
unknown committed
428
429
	uint index = rough ? 0 : 1;
	index = material.specular_exponent <= 1 ? 2 : index;
430

unknown's avatar
unknown committed
431
432
	index += transparent ? 3 : 0;
	index = (transparent && material.ior==1) ? 6 : index;
433

unknown's avatar
unknown committed
434
	index = emits ? 7 : index;
435

Johannes Braun's avatar
Johannes Braun committed
436
	//return sampleGGX(material, random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
unknown's avatar
unknown committed
437
	return u_bsdf_sample[index](material, random, vertex, ray_in, ray_out, light_influence, pdf, bsdf_id);
438
439
}

Johannes Braun's avatar
Johannes Braun committed
440
#endif //!__BDSF_DIFFUSE_GLH