Browse Source

PBR Materials example;

bjorn 7 years ago
parent
commit
30de07497a

+ 0 - 48
examples/Lighting/main.lua

@@ -1,48 +0,0 @@
-function lovr.load()
-  shader = lovr.graphics.newShader([[
-    out vec3 lightDirection;
-    out vec3 normalDirection;
-
-    vec3 lightPosition = vec3(0, 3, 3);
-
-    vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
-      vec4 vVertex = transform * vec4(lovrPosition, 1.);
-      vec4 vLight = lovrView * vec4(lightPosition, 1.);
-
-      lightDirection = normalize(vec3(vLight - vVertex));
-      normalDirection = normalize(lovrNormalMatrix * lovrNormal);
-
-      return projection * transform * vertex;
-    }
-  ]], [[
-    in vec3 lightDirection;
-    in vec3 normalDirection;
-
-    vec3 cAmbient = vec3(.25);
-    vec3 cDiffuse = vec3(.75);
-    vec3 cSpecular = vec3(.35);
-
-    vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {
-      float diffuse = max(dot(normalDirection, lightDirection), 0.);
-      float specular = 0.;
-
-      if (diffuse > 0.) {
-        vec3 r = reflect(lightDirection, normalDirection);
-        vec3 viewDirection = normalize(-vec3(gl_FragCoord));
-
-        float specularAngle = max(dot(r, viewDirection), 0.);
-        specular = pow(specularAngle, 5.);
-      }
-
-      vec3 cFinal = vec3(diffuse) * cDiffuse + vec3(specular) * cSpecular;
-      cFinal = clamp(cFinal, cAmbient, vec3(1.));
-      return vec4(cFinal, 1.) * graphicsColor * texture(image, uv);
-    }
-  ]])
-
-  lovr.graphics.setShader(shader)
-end
-
-function lovr.draw()
-  lovr.graphics.cube('fill', 0, 1.7, -1, .5, lovr.timer.getTime(), 0, 1, 0)
-end

+ 1 - 1
examples/Lighting/conf.lua → examples/PBR_Materials/conf.lua

@@ -1,4 +1,4 @@
 function lovr.conf(t)
   t.window.msaa = 4
-  t.gammacorrect = true
+  t.gammacorrect = lovr.getOS() ~= 'Web'
 end

BIN
examples/PBR_Materials/helmet/DamagedHelmet.bin


+ 204 - 0
examples/PBR_Materials/helmet/DamagedHelmet.gltf

@@ -0,0 +1,204 @@
+{
+    "accessors" : [
+        {
+            "bufferView" : 0,
+            "componentType" : 5123,
+            "count" : 46356,
+            "max" : [
+                14555
+            ],
+            "min" : [
+                0
+            ],
+            "type" : "SCALAR"
+        },
+        {
+            "bufferView" : 1,
+            "componentType" : 5126,
+            "count" : 14556,
+            "max" : [
+                0.9424954056739807,
+                0.8128451108932495,
+                0.900973916053772
+            ],
+            "min" : [
+                -0.9474585652351379,
+                -1.18715500831604,
+                -0.9009949564933777
+            ],
+            "type" : "VEC3"
+        },
+        {
+            "bufferView" : 2,
+            "componentType" : 5126,
+            "count" : 14556,
+            "max" : [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "min" : [
+                -1.0,
+                -1.0,
+                -1.0
+            ],
+            "type" : "VEC3"
+        },
+        {
+            "bufferView" : 3,
+            "componentType" : 5126,
+            "count" : 14556,
+            "max" : [
+                0.9999759793281555,
+                1.998665988445282
+            ],
+            "min" : [
+                0.002448640065267682,
+                1.0005531199858524
+            ],
+            "type" : "VEC2"
+        }
+    ],
+    "asset" : {
+        "generator" : "Khronos Blender glTF 2.0 exporter",
+        "version" : "2.0"
+    },
+    "bufferViews" : [
+        {
+            "buffer" : 0,
+            "byteLength" : 92712,
+            "byteOffset" : 0,
+            "target" : 34963
+        },
+        {
+            "buffer" : 0,
+            "byteLength" : 174672,
+            "byteOffset" : 92712,
+            "target" : 34962
+        },
+        {
+            "buffer" : 0,
+            "byteLength" : 174672,
+            "byteOffset" : 267384,
+            "target" : 34962
+        },
+        {
+            "buffer" : 0,
+            "byteLength" : 116448,
+            "byteOffset" : 442056,
+            "target" : 34962
+        }
+    ],
+    "buffers" : [
+        {
+            "byteLength" : 558504,
+            "uri" : "DamagedHelmet.bin"
+        }
+    ],
+    "images" : [
+        {
+            "uri" : "Default_albedo.jpg"
+        },
+        {
+            "uri" : "Default_metalRoughness.jpg"
+        },
+        {
+            "uri" : "Default_emissive.jpg"
+        },
+        {
+            "uri" : "Default_AO.jpg"
+        },
+        {
+            "uri" : "Default_normal.jpg"
+        }
+    ],
+    "materials" : [
+        {
+            "emissiveFactor" : [
+                1.0,
+                1.0,
+                1.0
+            ],
+            "emissiveTexture" : {
+                "index" : 2
+            },
+            "name" : "Material_MR",
+            "normalTexture" : {
+                "index" : 4
+            },
+            "occlusionTexture" : {
+                "index" : 3
+            },
+            "pbrMetallicRoughness" : {
+                "baseColorTexture" : {
+                    "index" : 0
+                },
+                "metallicRoughnessTexture" : {
+                    "index" : 1
+                }
+            }
+        }
+    ],
+    "meshes" : [
+        {
+            "name" : "mesh_helmet_LP_13930damagedHelmet",
+            "primitives" : [
+                {
+                    "attributes" : {
+                        "NORMAL" : 2,
+                        "POSITION" : 1,
+                        "TEXCOORD_0" : 3
+                    },
+                    "indices" : 0,
+                    "material" : 0
+                }
+            ]
+        }
+    ],
+    "nodes" : [
+        {
+            "mesh" : 0,
+            "name" : "node_damagedHelmet_-6514",
+            "rotation" : [
+                0.7071068286895752,
+                0.0,
+                -0.0,
+                0.7071068286895752
+            ]
+        }
+    ],
+    "samplers" : [
+        {}
+    ],
+    "scene" : 0,
+    "scenes" : [
+        {
+            "name" : "Scene",
+            "nodes" : [
+                0
+            ]
+        }
+    ],
+    "textures" : [
+        {
+            "sampler" : 0,
+            "source" : 0
+        },
+        {
+            "sampler" : 0,
+            "source" : 1
+        },
+        {
+            "sampler" : 0,
+            "source" : 2
+        },
+        {
+            "sampler" : 0,
+            "source" : 3
+        },
+        {
+            "sampler" : 0,
+            "source" : 4
+        }
+    ]
+}

BIN
examples/PBR_Materials/helmet/Default_AO.jpg


BIN
examples/PBR_Materials/helmet/Default_albedo.jpg


BIN
examples/PBR_Materials/helmet/Default_emissive.jpg


BIN
examples/PBR_Materials/helmet/Default_metalRoughness.jpg


BIN
examples/PBR_Materials/helmet/Default_normal.jpg


+ 107 - 0
examples/PBR_Materials/main.lua

@@ -0,0 +1,107 @@
+local glsl = {}
+local lightPosition = {}
+local headsetPosition = {}
+local controller = nil
+
+function lovr.load()
+  model = lovr.graphics.newModel('helmet/DamagedHelmet.gltf')
+  shader = lovr.graphics.newShader(unpack(glsl.pbr))
+  lovr.graphics.setBackgroundColor(.18, .18, .20)
+  lightPosition = { 75, 60, 20 }
+end
+
+function lovr.update(dt)
+  controller = lovr.headset.getControllers()[1]
+  if controller then lightPosition = { controller:getPosition() } end
+  headsetPosition = { lovr.headset.getPosition() }
+
+  shader:send('lightPosition', lightPosition)
+  shader:send('headsetPosition', headsetPosition)
+end
+
+function lovr.draw()
+  lovr.graphics.setShader(shader)
+  model:draw(0, 1.6, -1.5, .4, lovr.timer.getTime() * .12 + .1)
+  lovr.graphics.setShader()
+
+  if controller then
+    local x, y, z = unpack(lightPosition)
+    lovr.graphics.setColor(1, 1, 1)
+    lovr.graphics.sphere(x, y, z, .01)
+  end
+end
+
+glsl.pbr = {
+[[
+out vec3 vNormal;
+out vec3 vVertex;
+
+vec4 position(mat4 projection, mat4 transform, vec4 vertex) {
+  vNormal = mat3(lovrModel) * lovrNormal;
+  vVertex = vec3(lovrModel * vertex);
+  return projection * lovrView * vec4(vVertex, 1.0);
+}
+]],
+
+[[
+#define PI 3.141592653
+
+in vec3 vNormal;
+in vec3 vVertex;
+
+uniform vec3 headsetPosition;
+uniform vec3 lightPosition;
+
+float D_GGX(float NoH, float roughness) {
+  float alpha = roughness * roughness;
+  float alpha2 = alpha * alpha;
+  float denom = (NoH * NoH) * (alpha2 - 1.) + 1.;
+  return alpha2 / (PI * denom * denom);
+}
+
+float G_SmithGGXCorrelated(float NoV, float NoL, float roughness) {
+  float alpha = roughness * roughness;
+  float alpha2 = alpha * alpha;
+  float GGXV = NoL * sqrt(alpha2 + (1. - alpha2) * (NoV * NoV));
+  float GGXL = NoV * sqrt(alpha2 + (1. - alpha2) * (NoL * NoL));
+  return .5 / max(GGXV + GGXL, 1e-5);
+}
+
+vec3 F_Schlick(vec3 F0, float LoH) {
+  return F0 + (vec3(1.) - F0) * pow(1. - LoH, 5.);
+}
+
+vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) {
+  vec3 baseColor = texture(lovrDiffuseTexture, uv).rgb;
+  vec3 emissive = texture(lovrEmissiveTexture, uv).rgb;
+  float metalness = texture(lovrMetalnessTexture, uv).b * lovrMetalness;
+  float roughness = max(texture(lovrRoughnessTexture, uv).g * lovrRoughness, .05);
+  float occlusion = texture(lovrOcclusionTexture, uv).r;
+  vec3 F0 = mix(vec3(.04), baseColor, metalness);
+
+  vec3 N = normalize(vNormal);
+  vec3 V = normalize(headsetPosition - vVertex);
+  vec3 L = normalize(lightPosition - vVertex);
+  vec3 H = normalize(V + L);
+
+  float NoV = abs(dot(N, V)) + 1e-5;
+  float NoL = clamp(dot(N, L), 0., 1.);
+  float NoH = clamp(dot(N, H), 0., 1.);
+  float LoH = clamp(dot(L, H), 0., 1.);
+
+  float D = D_GGX(NoH, roughness);
+  float G = G_SmithGGXCorrelated(NoV, NoL, roughness);
+  vec3 F = F_Schlick(F0, LoH);
+
+  vec3 specular = vec3(D * G * F);
+  vec3 diffuse = (vec3(1.) - F) * (1. - metalness) * baseColor;
+  vec3 color = (diffuse + specular) * NoL * occlusion + emissive;
+
+]] ..
+(lovr.getOS() == 'Web' and '  color = pow(color, vec3(.4545));\n' or '') ..
+[[
+
+  return vec4(vec3(color), 1.);
+}
+]]
+}

+ 1 - 1
examples/init.lua

@@ -5,9 +5,9 @@ return {
   '3D_Model',
   'Animation',
   'Physics',
+  'PBR_Materials',
   'Cubemap',
   'Instancing',
   'Primitives',
-  'Lighting',
   'Microphone'
 }