diff --git a/data/textures/acubexneg2.png b/data/textures/acubexneg2.png new file mode 100644 index 00000000..2c626cfc Binary files /dev/null and b/data/textures/acubexneg2.png differ diff --git a/data/textures/acubexpos2.png b/data/textures/acubexpos2.png new file mode 100644 index 00000000..6bae4ca6 Binary files /dev/null and b/data/textures/acubexpos2.png differ diff --git a/data/textures/acubeyneg2.png b/data/textures/acubeyneg2.png new file mode 100644 index 00000000..0254fbd3 Binary files /dev/null and b/data/textures/acubeyneg2.png differ diff --git a/data/textures/acubeypos2.png b/data/textures/acubeypos2.png new file mode 100644 index 00000000..498b8b06 Binary files /dev/null and b/data/textures/acubeypos2.png differ diff --git a/data/textures/acubezneg2.png b/data/textures/acubezneg2.png new file mode 100644 index 00000000..94d38eff Binary files /dev/null and b/data/textures/acubezneg2.png differ diff --git a/data/textures/acubezpos2.png b/data/textures/acubezpos2.png new file mode 100644 index 00000000..d7adfbfe Binary files /dev/null and b/data/textures/acubezpos2.png differ diff --git a/src/DifBuilder.hx b/src/DifBuilder.hx index 19621a6c..9e6c5891 100644 --- a/src/DifBuilder.hx +++ b/src/DifBuilder.hx @@ -1,5 +1,6 @@ package src; +import shaders.DefaultCubemapMaterial; import shaders.DefaultNormalMaterial; import shaders.DefaultMaterial; import h3d.scene.Mesh; @@ -212,6 +213,38 @@ class DifBuilder { worker.run(); } + static function createDefaultCubemapMaterial(onFinish:hxsl.Shader->Void, baseTexture:String, normalTexture:String, shininess:Float, specularColor:Vector, + uvScaleFactor:Float = 1) { + var worker = new ResourceLoaderWorker(() -> { + var diffuseTex = ResourceLoader.getTexture(baseTexture).resource; + diffuseTex.wrap = Repeat; + diffuseTex.mipMap = Nearest; + var normalTex = ResourceLoader.getTexture(normalTexture).resource; + normalTex.wrap = Repeat; + normalTex.mipMap = Nearest; + + var cubemapTex = new h3d.mat.Texture(128, 128, [Cube]); + var cubemapFace1 = ResourceLoader.getImage('data/textures/acubexpos2.png').resource; + var cubemapFace2 = ResourceLoader.getImage('data/textures/acubexneg2.png').resource; + var cubemapFace3 = ResourceLoader.getImage('data/textures/acubezneg2.png').resource; + var cubemapFace4 = ResourceLoader.getImage('data/textures/acubezpos2.png').resource; + var cubemapFace5 = ResourceLoader.getImage('data/textures/acubeypos2.png').resource; + var cubemapFace6 = ResourceLoader.getImage('data/textures/acubeyneg2.png').resource; + cubemapTex.uploadPixels(cubemapFace1.getPixels(), 0, 0); + cubemapTex.uploadPixels(cubemapFace2.getPixels(), 0, 1); + cubemapTex.uploadPixels(cubemapFace3.getPixels(), 0, 2); + cubemapTex.uploadPixels(cubemapFace4.getPixels(), 0, 3); + cubemapTex.uploadPixels(cubemapFace5.getPixels(), 0, 4); + cubemapTex.uploadPixels(cubemapFace6.getPixels(), 0, 5); + + var shader = new DefaultCubemapMaterial(diffuseTex, normalTex, shininess, specularColor, uvScaleFactor, cubemapTex); + onFinish(shader); + }); + worker.loadFile(baseTexture); + worker.loadFile(normalTexture); + worker.run(); + } + static function createDefaultNormalMaterial(onFinish:hxsl.Shader->Void, baseTexture:String, shininess:Float, specularColor:Vector, uvScaleFactor:Float = 1) { var worker = new ResourceLoaderWorker(() -> { @@ -294,10 +327,10 @@ class DifBuilder { 'beam' => (onFinish) -> createDefaultMaterial(onFinish, 'data/textures/beam.png', 'data/textures/beam.normal.png', 12, new Vector(0.8, 0.8, 0.6, 1)), 'beam_side' => (onFinish) -> createDefaultMaterial(onFinish, 'data/textures/beam_side.png', 'data/textures/beam_side.normal.png', 12, new Vector(0.8, 0.8, 0.6, 1)), - // 'friction_low.png' => (onFinish) -> createPhongMaterial(onFinish, 'data/textures/friction_low.png', 'data/textures/friction_low.normal.png', 128, - // new Vector(1, 1, 1, 0.8)), - // 'friction_low_shadow' => (onFinish) -> createPhongMaterial(onFinish, 'data/textures/friction_low_shadow.png', 'data/textures/friction_low.normal.png', - // 128, new Vector(0.3, 0.3, 0.35, 1)), + 'friction_low' => (onFinish) -> createDefaultCubemapMaterial(onFinish, 'data/textures/friction_low.png', 'data/textures/friction_low.normal.png', 128, + new Vector(1, 1, 1, 0.8)), + 'friction_low_shadow' => (onFinish) -> createDefaultCubemapMaterial(onFinish, 'data/textures/friction_low_shadow.png', + 'data/textures/friction_low.normal.png', 128, new Vector(0.3, 0.3, 0.35, 1)), 'friction_high' => (onFinish) -> createDefaultMaterial(onFinish, 'data/textures/friction_high.png', 'data/textures/friction_high.normal.png', 10, new Vector(0.3, 0.3, 0.35, 1)), 'friction_high_shadow' => (onFinish) -> createDefaultMaterial(onFinish, 'data/textures/friction_high_shadow.png', diff --git a/src/InstanceManager.hx b/src/InstanceManager.hx index f5610585..2b4b01eb 100644 --- a/src/InstanceManager.hx +++ b/src/InstanceManager.hx @@ -138,38 +138,55 @@ class InstanceManager { } if (isMesh) { var mat = cast(obj, Mesh).material; - var dtsshader = mat.mainPass.getShader(DtsTexture); - if (dtsshader != null) { - minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - minfo.meshbatch.material.mainPass.addShader(dtsshader); - minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; - minfo.meshbatch.material.mainPass.depthWrite = mat.mainPass.depthWrite; + var minfoshaders = []; + for (shader in minfo.meshbatch.material.mainPass.getShaders()) { + minfoshaders.push(shader); } - var phongshader = mat.mainPass.getShader(PhongMaterial); - if (phongshader != null) { - minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - minfo.meshbatch.material.mainPass.addShader(phongshader); - // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; - } - var noiseshder = mat.mainPass.getShader(NoiseTileMaterial); - if (noiseshder != null) { - minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - minfo.meshbatch.material.mainPass.addShader(noiseshder); - // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; - } - var nmapshdr = mat.mainPass.getShader(NormalMaterial); - if (nmapshdr != null) { - minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - minfo.meshbatch.material.mainPass.addShader(nmapshdr); - // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; - } - var cubemapshdr = mat.mainPass.getShader(EnvMap); - if (cubemapshdr != null) { - minfo.meshbatch.material.mainPass.addShader(cubemapshdr); + for (shader in minfoshaders) + minfo.meshbatch.material.mainPass.removeShader(shader); + for (shader in mat.mainPass.getShaders()) { + minfo.meshbatch.material.mainPass.addShader(shader); } + // var dtsshader = mat.mainPass.getShader(DtsTexture); + // if (dtsshader != null) { + // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + // minfo.meshbatch.material.mainPass.addShader(dtsshader); + // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; + // minfo.meshbatch.material.mainPass.depthWrite = mat.mainPass.depthWrite; + // } + // var phongshader = mat.mainPass.getShader(PhongMaterial); + // if (phongshader != null) { + // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + // minfo.meshbatch.material.mainPass.addShader(phongshader); + // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; + // } + // var noiseshder = mat.mainPass.getShader(NoiseTileMaterial); + // if (noiseshder != null) { + // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + // minfo.meshbatch.material.mainPass.addShader(noiseshder); + // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; + // } + // var nmapshdr = mat.mainPass.getShader(NormalMaterial); + // if (nmapshdr != null) { + // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); + // minfo.meshbatch.material.mainPass.addShader(nmapshdr); + // // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; + // } + // var cubemapshdr = mat.mainPass.getShader(EnvMap); + // if (cubemapshdr != null) { + // minfo.meshbatch.material.mainPass.addShader(cubemapshdr); + // } minfo.transparencymeshbatch = new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene); + minfoshaders = []; + for (shader in minfo.transparencymeshbatch.material.mainPass.getShaders()) { + minfoshaders.push(shader); + } + for (shader in minfoshaders) + minfo.transparencymeshbatch.material.mainPass.removeShader(shader); minfo.transparencymeshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); - minfo.transparencymeshbatch.material.mainPass.addShader(dtsshader); + for (shader in mat.mainPass.getShaders()) { + minfo.transparencymeshbatch.material.mainPass.addShader(shader); + } // minfo.transparencymeshbatch.material.mainPass.culling = mat.mainPass.culling; // minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.mainPass.getShader(PropsValues)); diff --git a/src/InteriorObject.hx b/src/InteriorObject.hx index 597fea2d..9aeaf8f2 100644 --- a/src/InteriorObject.hx +++ b/src/InteriorObject.hx @@ -10,7 +10,7 @@ import h3d.scene.Object; class InteriorObject extends GameObject { public var collider:CollisionEntity; public var interiorFile:String; - public var useInstancing = false; + public var useInstancing = true; public var level:MarbleWorld; public function new() { diff --git a/src/shaders/DefaultCubemapMaterial.hx b/src/shaders/DefaultCubemapMaterial.hx new file mode 100644 index 00000000..200a2078 --- /dev/null +++ b/src/shaders/DefaultCubemapMaterial.hx @@ -0,0 +1,104 @@ +package shaders; + +class DefaultCubemapMaterial extends hxsl.Shader { + static var SRC = { + @param var diffuseMap:Sampler2D; + @param var specularColor:Vec4; + @param var normalMap:Sampler2D; + @param var cubeMap:SamplerCube; + @param var shininess:Float; + @param var secondaryMapUvFactor:Float; + @global var camera:{ + var position:Vec3; + @var var dir:Vec3; + }; + @global var global:{ + @perObject var modelView:Mat4; + @perObject var modelViewInverse:Mat4; + }; + @input var input:{ + var position:Vec3; + var normal:Vec3; + var uv:Vec2; + var t:Vec3; + var b:Vec3; + var n:Vec3; + }; + var calculatedUV:Vec2; + var pixelColor:Vec4; + var specColor:Vec3; + var specPower:Float; + var pixelTransformedPosition:Vec3; + var transformedNormal:Vec3; + // @var var outReflectVec:Vec3; + @var var outLightVec:Vec4; + @var var outPos:Vec3; + @var var outEyePos:Vec3; + function lambert(normal:Vec3, lightPosition:Vec3):Float { + var result = dot(normal, lightPosition); + return saturate(result); + } + function vertex() { + var eyePos = camera.position * mat3x4(global.modelViewInverse); + // eyePos /= vec3(global.modelViewInverse[0].x, global.modelViewInverse[1].y, global.modelViewInverse[2].z); + var cubeTrans = mat3(global.modelView); + var cubeEyePos = camera.position - global.modelView[3].xyz; + + calculatedUV = input.uv; + + var objToTangentSpace = mat3(input.t, input.b, input.n); + outLightVec = vec4(0); + + var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewInverse); + outLightVec.xyz = -inLightVec * objToTangentSpace; + // var cubeVertPos = input.position * cubeTrans; + // var cubeNormal = input.normal * cubeTrans; + // var eyeToVert = (cubeVertPos - cubeEyePos).normalize(); + // outReflectVec = reflect(eyeToVert, cubeNormal); + outPos = (input.position / 100.0) * objToTangentSpace; + outEyePos = (eyePos / 100.0) * objToTangentSpace; + outLightVec.w = step(-0.5, dot(input.normal, -inLightVec)); + } + function fragment() { + var ambient = vec4(0.472, 0.424, 0.475, 1.00); + var shading = vec4(1.08, 1.03, 0.90, 1); + + var diffuse = diffuseMap.get(calculatedUV); + var outCol = diffuse; + var bumpNormal = unpackNormal(normalMap.get(calculatedUV * secondaryMapUvFactor)); + + var incidentRay = normalize(pixelTransformedPosition - camera.position); + var reflectionRay = reflect(incidentRay, transformedNormal); + + var bumpDot = ((dot(bumpNormal, outLightVec.xyz) + 1) * 0.5); + outCol *= (shading * bumpDot) + ambient; + outCol += diffuse.a * cubeMap.get(reflectionRay); + + var eyeVec = (outEyePos - outPos).normalize(); + var halfAng = (eyeVec + outLightVec.xyz).normalize(); + var specValue = saturate(bumpNormal.dot(halfAng)) * outLightVec.w; + var specular = specularColor * pow(specValue, shininess); + + outCol += specular * diffuse.a; + + // Gamma correction using our regression model + var a = 1.00759; + var b = 1.18764; + outCol.x = a * pow(outCol.x, b); + outCol.y = a * pow(outCol.y, b); + outCol.z = a * pow(outCol.z, b); + + pixelColor = outCol; + } + } + + public function new(diffuse, normal, shininess, specularColor, secondaryMapUvFactor, skybox) { + super(); + this.diffuseMap = diffuse; + this.cubeMap = skybox; + this.normalMap = normal; + this.shininess = shininess; + this.specularColor = specularColor; + this.secondaryMapUvFactor = secondaryMapUvFactor; + } +} diff --git a/src/shaders/DefaultMaterial.hx b/src/shaders/DefaultMaterial.hx index aeba064d..e134e269 100644 --- a/src/shaders/DefaultMaterial.hx +++ b/src/shaders/DefaultMaterial.hx @@ -44,7 +44,7 @@ class DefaultMaterial extends hxsl.Shader { outLightVec = vec4(0); var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewInverse); var eyePos = camera.position * mat3x4(global.modelViewInverse); - eyePos /= vec3(global.modelViewInverse[0].x, global.modelViewInverse[1].y, global.modelViewInverse[2].z); + // eyePos /= vec3(global.modelViewInverse[0].x, global.modelViewInverse[1].y, global.modelViewInverse[2].z); outLightVec.xyz = -inLightVec * objToTangentSpace; outPos = (input.position / 100.0) * objToTangentSpace; outEyePos = (eyePos / 100.0) * objToTangentSpace; diff --git a/src/shaders/DefaultNormalMaterial.hx b/src/shaders/DefaultNormalMaterial.hx index ac622aea..d025111f 100644 --- a/src/shaders/DefaultNormalMaterial.hx +++ b/src/shaders/DefaultNormalMaterial.hx @@ -38,7 +38,7 @@ class DefaultNormalMaterial extends hxsl.Shader { outLightVec = vec4(0); var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewInverse); var eyePos = camera.position * mat3x4(global.modelViewInverse); - eyePos /= vec3(global.modelViewInverse[0].x, global.modelViewInverse[1].y, global.modelViewInverse[2].z); + // eyePos /= vec3(global.modelViewInverse[0].x, global.modelViewInverse[1].y, global.modelViewInverse[2].z); outLightVec.xyz = -inLightVec; outLightVec.w = step(-0.5, dot(input.normal, -inLightVec)); outEyePos = eyePos; diff --git a/src/shaders/NoiseTileMaterial.hx b/src/shaders/NoiseTileMaterial.hx index ea6e25dd..71e91e85 100644 --- a/src/shaders/NoiseTileMaterial.hx +++ b/src/shaders/NoiseTileMaterial.hx @@ -41,7 +41,7 @@ class NoiseTileMaterial extends hxsl.Shader { outLightVec = vec4(0); var inLightVec = vec3(-0.5732, 0.27536, -0.77176) * mat3(global.modelViewInverse); var eyePos = camera.position * mat3x4(global.modelViewInverse); - eyePos /= vec3(global.modelViewInverse[0].x, global.modelViewInverse[1].y, global.modelViewInverse[2].z); + // eyePos /= vec3(global.modelViewInverse[0].x, global.modelViewInverse[1].y, global.modelViewInverse[2].z); outLightVec.xyz = -inLightVec * objToTangentSpace; outPos = (input.position / 100.0) * objToTangentSpace; outEyePos = (eyePos / 100.0) * objToTangentSpace;