Skip to content

Commit 5e37f5e

Browse files
Add Transmission material param, onb, experimental microfacet transmission
1 parent 2e683f2 commit 5e37f5e

File tree

8 files changed

+259
-104
lines changed

8 files changed

+259
-104
lines changed

src/Main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,8 @@ void MainLoop(void* arg)
348348
objectPropChanged |= ImGui::SliderFloat("SheenTint", &scene->materials[scene->meshInstances[selectedInstance].materialID].sheenTint, 0.001f, 1.0f);
349349
objectPropChanged |= ImGui::SliderFloat("Clearcoat", &scene->materials[scene->meshInstances[selectedInstance].materialID].clearcoat, 0.001f, 1.0f);
350350
objectPropChanged |= ImGui::SliderFloat("ClearcoatGloss", &scene->materials[scene->meshInstances[selectedInstance].materialID].clearcoatGloss, 0.001f, 1.0f);
351+
objectPropChanged |= ImGui::SliderFloat("Transmission", &scene->materials[scene->meshInstances[selectedInstance].materialID].transmission, 0.001f, 1.0f);
352+
objectPropChanged |= ImGui::SliderFloat("Ior", &scene->materials[scene->meshInstances[selectedInstance].materialID].ior, 1.0f, 2.0f);
351353

352354
// Transforms Properties
353355
ImGui::Separator();

src/core/Material.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,15 @@ namespace GLSLPT
5555
clearcoat = 0.0f;
5656
clearcoatGloss = 0.0f;
5757

58+
transmission = 0.0f;
59+
ior = 1.45f;
60+
unused1 = 0.0f;
61+
unused2 = 0.0f;
62+
5863
albedoTexID = -1.0f;
5964
metallicRoughnessTexID = -1.0f;
6065
normalmapTexID = -1.0f;
61-
ior = 1.45f;
66+
unused3 = 0.0f;
6267
};
6368

6469
Vec3 albedo;
@@ -77,9 +82,14 @@ namespace GLSLPT
7782
float clearcoat;
7883
float clearcoatGloss;
7984

85+
float transmission;
86+
float ior;
87+
float unused1;
88+
float unused2;
89+
8090
float albedoTexID;
8191
float metallicRoughnessTexID;
8292
float normalmapTexID;
83-
float ior;
93+
float unused3;
8494
};
8595
}

src/loaders/Loader.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ namespace GLSLPT
110110
sscanf(line, " sheenTint %f", &material.sheenTint);
111111
sscanf(line, " clearcoat %f", &material.clearcoat);
112112
sscanf(line, " clearcoatGloss %f", &material.clearcoatGloss);
113+
sscanf(line, " transmission %f", &material.transmission);
113114
sscanf(line, " ior %f", &material.ior);
114115
//sscanf(line, " transmittance %f", &material.transmittance);
115116

src/shaders/common/brdf.glsl

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,13 @@ float DisneyPdf(in Ray ray, inout State state, in vec3 bsdfDir)
4343
float diffuseRatio = 0.5 * (1.0 - state.mat.metallic);
4444
float specularRatio = 1.0 - diffuseRatio;
4545

46-
float cosTheta = abs(dot(H, N));
47-
48-
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
49-
vec3 X = normalize(cross(UpVector, N));
50-
vec3 Y = cross(N, X);
51-
5246
float aspect = sqrt(1.0 - state.mat.anisotropic * 0.9);
5347
float ax = max(0.001, (state.mat.roughness * state.mat.roughness) / aspect);
5448
float ay = max(0.001, (state.mat.roughness * state.mat.roughness) * aspect);
55-
float pdfGTR2 = GTR2_aniso(NDotH, dot(H, X), dot(H, Y), ax, ay) * cosTheta;
56-
float pdfGTR1 = GTR1(cosTheta, clearcoatAlpha) * cosTheta;
5749

5850
// calculate diffuse and specular pdfs and mix ratio
51+
float pdfGTR2 = GTR2_aniso(NDotH, dot(H, state.tangent), dot(H, state.bitangent), ax, ay) * NDotH;
52+
float pdfGTR1 = GTR1(NDotH, clearcoatAlpha) * NDotH;
5953
float ratio = 1.0 / (1.0 + state.mat.clearcoat);
6054
float pdfSpec = mix(pdfGTR1, pdfGTR2, ratio) / (4.0 * abs(dot(L, H)));
6155
float pdfDiff = abs(dot(L, N)) * (1.0 / PI);
@@ -79,14 +73,10 @@ vec3 DisneySample(in Ray ray, inout State state)
7973
float r1 = rand();
8074
float r2 = rand();
8175

82-
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
83-
vec3 TangentX = normalize(cross(UpVector, N));
84-
vec3 TangentY = cross(N, TangentX);
85-
8676
if (probability < diffuseRatio) // sample diffuse
8777
{
8878
dir = CosineSampleHemisphere(r1, r2);
89-
dir = TangentX * dir.x + TangentY * dir.y + N * dir.z;
79+
dir = state.tangent * dir.x + state.bitangent * dir.y + N * dir.z;
9080
}
9181
else
9282
{
@@ -100,7 +90,7 @@ vec3 DisneySample(in Ray ray, inout State state)
10090
float cosPhi = cos(phi);
10191

10292
vec3 H = vec3(sinTheta*cosPhi, sinTheta*sinPhi, cosTheta);
103-
H = TangentX * H.x + TangentY * H.y + N * H.z;
93+
H = state.tangent * H.x + state.bitangent * H.y + N * H.z;
10494

10595
dir = 2.0*dot(V, H)*H - V;
10696
}
@@ -147,7 +137,7 @@ vec3 DisneyEval(in Ray ray, inout State state, in vec3 bsdfDir)
147137
float ss = 1.25 * (Fss * (1.0 / (NDotL + NDotV) - 0.5) + 0.5);
148138

149139
// specular
150-
/*float a = max(0.001f, state.mat.roughness);
140+
/*float a = max(0.001, state.mat.roughness);
151141
float Ds = GTR2(NDotH, a);
152142
float FH = SchlickFresnel(LDotH);
153143
vec3 Fs = mix(Cspec0, vec3(1.0), FH);
@@ -156,18 +146,14 @@ vec3 DisneyEval(in Ray ray, inout State state, in vec3 bsdfDir)
156146
float Gs = SmithG_GGX(NDotL, roughg) * SmithG_GGX(NDotV, roughg);*/
157147

158148
// specular
159-
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
160-
vec3 X = normalize(cross(UpVector, N));
161-
vec3 Y = cross(N, X);
162-
163149
float aspect = sqrt(1.0 - state.mat.anisotropic * 0.9);
164150
float ax = max(0.001, (state.mat.roughness * state.mat.roughness) / aspect);
165151
float ay = max(0.001, (state.mat.roughness * state.mat.roughness) * aspect);
166-
float Ds = GTR2_aniso(NDotH, dot(H, X), dot(H, Y), ax, ay);
152+
float Ds = GTR2_aniso(NDotH, dot(H, state.tangent), dot(H, state.bitangent), ax, ay);
167153
float FH = SchlickFresnel(LDotH);
168154
vec3 Fs = mix(Cspec0, vec3(1.0), FH);
169-
float Gs = SmithG_GGX_aniso(NDotL, dot(L, X), dot(L, Y), ax, ay);
170-
Gs *= SmithG_GGX_aniso(NDotV, dot(V, X), dot(V, Y), ax, ay);
155+
float Gs = SmithG_GGX_aniso(NDotL, dot(L, state.tangent), dot(L, state.bitangent), ax, ay);
156+
Gs *= SmithG_GGX_aniso(NDotV, dot(V, state.tangent), dot(V, state.bitangent), ax, ay);
171157

172158
// sheen
173159
vec3 Fsheen = FH * state.mat.sheen * Csheen;

src/shaders/common/glass.glsl

Lines changed: 104 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,53 +28,127 @@
2828
*/
2929

3030
//-----------------------------------------------------------------------
31-
float GlassPdf(Ray ray, inout State state)
31+
float GlassPdf(Ray ray, inout State state, in vec3 bsdfDir)
3232
//-----------------------------------------------------------------------
3333
{
34-
return 1.0;
34+
vec3 N = state.ffnormal;
35+
vec3 V = -ray.direction;
36+
vec3 L = bsdfDir;
37+
38+
if (dot(N,L) <= 0.0)
39+
{
40+
L = -L;
41+
}
42+
43+
vec3 H = normalize(L + V);
44+
45+
float NDotH = abs(dot(N, H));
46+
float VDotH = abs(dot(V, H));
47+
48+
float a = max(0.001, state.mat.roughness);
49+
float pdfGTR2 = GTR2(NDotH, a) * NDotH;
50+
51+
float F = Fresnel(abs(dot(L, H)), 1.0, 1.45);
52+
53+
float n1 = 1.0;
54+
float n2 = 1.45;
55+
float eta = dot(state.normal, N) > 0.0 ? (n1 / n2) : (n2 / n1);
56+
57+
// Transmission Vector
58+
if (dot(N, L) < 0.0)
59+
{
60+
float denom = n1 * dot(V, H) + n2 * dot(L, H);
61+
return pdfGTR2 * (1.0 - F) * abs(dot(L, H)) / (denom * denom);
62+
//return 1.0;
63+
}
64+
else
65+
return pdfGTR2 * F / (4.0 * abs(dot(L, H)));
66+
3567
}
3668

3769
//-----------------------------------------------------------------------
3870
vec3 GlassSample(in Ray ray, inout State state)
3971
//-----------------------------------------------------------------------
4072
{
41-
/*float n1 = 1.0;
42-
float n2 = state.mat.param.z;
43-
float R0 = (n1 - n2) / (n1 + n2);
44-
R0 *= R0;
45-
float theta = dot(-ray.direction, state.ffnormal);
46-
float prob = R0 + (1. - R0) * SchlickFresnel(theta);
47-
vec3 dir;
73+
vec3 N = state.ffnormal;
74+
vec3 V = -ray.direction;
75+
76+
float r1 = rand();
77+
float r2 = rand();
78+
79+
vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
80+
vec3 TangentX = normalize(cross(UpVector, N));
81+
vec3 TangentY = cross(N, TangentX);
82+
83+
float a = max(0.001, state.mat.roughness);
84+
85+
float phi = r1 * 2.0 * PI;
4886

49-
//vec3 transmittance = vec3(1.0);
50-
//vec3 extinction = -log(vec3(0.1, 0.1, 0.908));
51-
//vec3 extinction = -log(vec3(0.905, 0.63, 0.3));
87+
float cosTheta = sqrt((1.0 - r2) / (1.0 + (a * a - 1.0) * r2));
88+
float sinTheta = clamp(sqrt(1.0 - (cosTheta * cosTheta)), 0.0, 1.0);
89+
float sinPhi = sin(phi);
90+
float cosPhi = cos(phi);
5291

53-
float eta = dot(state.normal, state.ffnormal) > 0.0 ? (n1 / n2) : (n2 / n1);
54-
vec3 transDir = normalize(refract(ray.direction, state.ffnormal, eta));
92+
vec3 H = vec3(sinTheta * cosPhi, sinTheta * sinPhi, cosTheta);
93+
H = TangentX * H.x + TangentY * H.y + N * H.z;
94+
95+
float n1 = 1.0;
96+
float n2 = 1.45;
97+
98+
float theta = abs(dot(-V, N));
99+
float eta = dot(state.normal, N) > 0.0 ? (n1 / n2) : (n2 / n1);
55100
float cos2t = 1.0 - eta * eta * (1.0 - theta * theta);
56101

57-
//if(dot(-ray.direction, state.normal) <= 0.0)
58-
// transmittance = exp(-extinction * state.hitDist * 100.0);
102+
float F = Fresnel(theta, n1, n2);
59103

60-
if (cos2t < 0.0 || rand() < prob) // Reflection
61-
{
62-
dir = normalize(reflect(ray.direction, state.ffnormal));
63-
}
64-
else // Transmission
65-
{
66-
dir = transDir;
67-
}
68-
//state.mat.albedo.xyz = transmittance;
69-
return dir;*/
104+
vec3 dir;
105+
if (cos2t < 0.0 || rand() < F)
106+
dir = normalize(reflect(-V, H));
107+
else
108+
dir = normalize(refract(-V, H, eta));
70109

71-
return vec3(1.0);
110+
return dir;
72111
}
73112

74113
//-----------------------------------------------------------------------
75-
vec3 GlassEval(in Ray ray, inout State state)
114+
vec3 GlassEval(in Ray ray, inout State state, in vec3 bsdfDir)
76115
//-----------------------------------------------------------------------
77116
{
78-
return vec3(1.0);
79-
//return state.mat.albedo.xyz;
117+
vec3 N = state.ffnormal;
118+
vec3 V = -ray.direction;
119+
vec3 L = bsdfDir;
120+
121+
float NDotL = dot(N, L);
122+
float NDotV = dot(N, V);
123+
124+
if (NDotL <= 0.0)
125+
{
126+
L = -L;
127+
}
128+
NDotL = dot(N, L);
129+
130+
vec3 H = normalize(L + V);
131+
132+
//if (NDotL <= 0.0 || NDotV <= 0.0)
133+
// return vec3(0.0);
134+
135+
float NDotH = abs(dot(N, H));
136+
float LDotH = abs(dot(L, H));
137+
float VDotH = abs(dot(V, H));
138+
139+
float n1 = 1.0;
140+
float n2 = 1.45;
141+
float a = max(0.001, state.mat.roughness);
142+
float D = GTR2(NDotH, a);
143+
float F = Fresnel(LDotH, n1, n2);
144+
float G = SmithG_GGX(NDotL, a) * SmithG_GGX(NDotV, a);
145+
146+
if (dot(N, L) < 0.0)
147+
{
148+
float denom = n1 * dot(V, H) + n2 * dot(L, H);
149+
return 4.0 * state.mat.albedo * (LDotH * VDotH) * (1.0 - F) * D * G / (denom * denom);
150+
//return vec3(1.0);
151+
}
152+
else
153+
return state.mat.albedo * F * D * G;
80154
}

src/shaders/common/globals.glsl

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,92 @@
3232
#define INFINITY 1000000.0
3333
#define EPS 0.001
3434

35-
// Global variables
36-
3735
mat4 transform;
3836

3937
vec2 seed;
4038
vec3 tempTexCoords;
41-
struct Ray { vec3 origin; vec3 direction; };
42-
struct Material { vec3 albedo; float specular; vec3 emission; float anisotropic; float metallic; float roughness; float subsurface; float specularTint; float sheen; float sheenTint; float clearcoat; float clearcoatGloss; vec4 texIDs; };
43-
struct Camera { vec3 up; vec3 right; vec3 forward; vec3 position; float fov; float focalDist; float aperture; };
44-
struct Light { vec3 position; vec3 emission; vec3 u; vec3 v; vec3 radiusAreaType; };
45-
struct State { vec3 normal; vec3 ffnormal; vec3 fhp; bool isEmitter; int depth; float hitDist; vec2 texCoord; vec3 bary; ivec3 triID; int matID; Material mat; bool specularBounce; };
46-
struct BsdfSampleRec { vec3 bsdfDir; float pdf; };
47-
struct LightSampleRec { vec3 surfacePos; vec3 normal; vec3 emission; float pdf; };
39+
40+
struct Ray
41+
{
42+
vec3 origin;
43+
vec3 direction;
44+
};
45+
46+
struct Material
47+
{
48+
vec3 albedo;
49+
float specular;
50+
vec3 emission;
51+
float anisotropic;
52+
float metallic;
53+
float roughness;
54+
float subsurface;
55+
float specularTint;
56+
float sheen;
57+
float sheenTint;
58+
float clearcoat;
59+
float clearcoatGloss;
60+
float transmission;
61+
float ior;
62+
vec4 texIDs;
63+
};
64+
65+
struct Camera
66+
{
67+
vec3 up;
68+
vec3 right;
69+
vec3 forward;
70+
vec3 position;
71+
float fov;
72+
float focalDist;
73+
float aperture;
74+
};
75+
76+
struct Light
77+
{
78+
vec3 position;
79+
vec3 emission;
80+
vec3 u;
81+
vec3 v;
82+
vec3 radiusAreaType;
83+
};
84+
85+
struct State
86+
{
87+
vec3 normal;
88+
vec3 ffnormal;
89+
vec3 tangent;
90+
vec3 bitangent;
91+
vec3 fhp;
92+
bool isEmitter;
93+
int depth;
94+
float hitDist;
95+
vec2 texCoord;
96+
vec3 bary;
97+
ivec3 triID;
98+
int matID;
99+
Material mat;
100+
};
101+
102+
struct BsdfSampleRec
103+
{
104+
vec3 bsdfDir;
105+
float pdf;
106+
};
107+
108+
struct LightSampleRec
109+
{
110+
vec3 surfacePos;
111+
vec3 normal;
112+
vec3 emission;
113+
float pdf;
114+
};
48115

49116
uniform Camera camera;
50117

51-
//-----------------------------------------------------------------------
118+
//-----------
52119
float rand()
53-
//-----------------------------------------------------------------------
120+
//-----------
54121
{
55122
seed -= randomVector.xy;
56123
return fract(sin(dot(seed, vec2(12.9898, 78.233))) * 43758.5453);

0 commit comments

Comments
 (0)