|
@@ -1,107 +1,48 @@
|
|
|
-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
|
|
|
+ model = lovr.graphics.newModel('helmet/DamagedHelmet.glb')
|
|
|
+
|
|
|
+ shader = lovr.graphics.newShader('standard', {
|
|
|
+ flags = {
|
|
|
+ normalTexture = false,
|
|
|
+ indirectLighting = true,
|
|
|
+ occlusion = true,
|
|
|
+ emissive = true,
|
|
|
+ skipTonemap = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ skybox = lovr.graphics.newTexture({
|
|
|
+ left = 'env/nx.png',
|
|
|
+ right = 'env/px.png',
|
|
|
+ top = 'env/py.png',
|
|
|
+ bottom = 'env/ny.png',
|
|
|
+ back = 'env/pz.png',
|
|
|
+ front = 'env/nz.png'
|
|
|
+ }, { linear = true })
|
|
|
+
|
|
|
+ environmentMap = lovr.graphics.newTexture(256, 256, { type = 'cube' })
|
|
|
+ for mipmap = 1, environmentMap:getMipmapCount() do
|
|
|
+ for face, dir in ipairs({ 'px', 'nx', 'py', 'ny', 'pz', 'nz' }) do
|
|
|
+ local filename = ('env/m%d_%s.png'):format(mipmap - 1, dir)
|
|
|
+ local image = lovr.data.newTextureData(filename, false)
|
|
|
+ environmentMap:replacePixels(image, 0, 0, face, mipmap)
|
|
|
+ end
|
|
|
+ end
|
|
|
|
|
|
-function lovr.update(dt)
|
|
|
- controller = lovr.headset.getControllers()[1]
|
|
|
- if controller then lightPosition = { controller:getPosition() } end
|
|
|
- headsetPosition = { lovr.headset.getPosition() }
|
|
|
+ shader:send('lovrLightDirection', { -1, -1, -1 })
|
|
|
+ shader:send('lovrLightColor', { .9, .9, .8, 1.0 })
|
|
|
+ shader:send('lovrExposure', 2)
|
|
|
+ shader:send('lovrSphericalHarmonics', require('env/sphericalHarmonics'))
|
|
|
+ shader:send('lovrEnvironmentMap', environmentMap)
|
|
|
|
|
|
- shader:send('lightPosition', lightPosition)
|
|
|
- shader:send('headsetPosition', headsetPosition)
|
|
|
+ lovr.graphics.setBackgroundColor(.18, .18, .20)
|
|
|
+ lovr.graphics.setCullingEnabled(true)
|
|
|
+ lovr.graphics.setBlendMode()
|
|
|
end
|
|
|
|
|
|
function lovr.draw()
|
|
|
+ lovr.graphics.skybox(skybox)
|
|
|
lovr.graphics.setShader(shader)
|
|
|
- model:draw(0, 1.6, -1.5, .4, lovr.timer.getTime() * .12 + .1)
|
|
|
+ model:draw(0, 1.5, -3, 1, lovr.timer.getTime() * .15 - 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.);
|
|
|
-}
|
|
|
-]]
|
|
|
-}
|