diff --git a/.gitignore b/.gitignore index 6f70b90c..55764f12 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,8 @@ native *.obj settings.json release -Export \ No newline at end of file +Export +node_modules +fonts +package.json +package-lock.json diff --git a/data/shaders/DefaultDiffuse.png b/data/shaders/DefaultDiffuse.png new file mode 100644 index 00000000..5a983c96 Binary files /dev/null and b/data/shaders/DefaultDiffuse.png differ diff --git a/data/shaders/DefaultNormal.png b/data/shaders/DefaultNormal.png new file mode 100644 index 00000000..09f9af73 Binary files /dev/null and b/data/shaders/DefaultNormal.png differ diff --git a/data/shaders/DefaultSpec.png b/data/shaders/DefaultSpec.png new file mode 100644 index 00000000..71237778 Binary files /dev/null and b/data/shaders/DefaultSpec.png differ diff --git a/data/shaders/tex/beam_side_mbu.normal.png b/data/shaders/tex/beam_side_mbu.normal.png new file mode 100644 index 00000000..9b5fded3 Binary files /dev/null and b/data/shaders/tex/beam_side_mbu.normal.png differ diff --git a/data/shaders/tex/bluegreen.normal.png b/data/shaders/tex/bluegreen.normal.png new file mode 100644 index 00000000..c368488a Binary files /dev/null and b/data/shaders/tex/bluegreen.normal.png differ diff --git a/data/shaders/tex/bluegreen.spec.png b/data/shaders/tex/bluegreen.spec.png new file mode 100644 index 00000000..5e8df3ac Binary files /dev/null and b/data/shaders/tex/bluegreen.spec.png differ diff --git a/data/shaders/tex/chevron_mbg.normal.png b/data/shaders/tex/chevron_mbg.normal.png new file mode 100644 index 00000000..ee6fcc79 Binary files /dev/null and b/data/shaders/tex/chevron_mbg.normal.png differ diff --git a/data/shaders/tex/chevron_mbg.spec.png b/data/shaders/tex/chevron_mbg.spec.png new file mode 100644 index 00000000..1f38d635 Binary files /dev/null and b/data/shaders/tex/chevron_mbg.spec.png differ diff --git a/data/shaders/tex/edge_white_mbu.normal.jpg b/data/shaders/tex/edge_white_mbu.normal.jpg new file mode 100644 index 00000000..9efd9b2a Binary files /dev/null and b/data/shaders/tex/edge_white_mbu.normal.jpg differ diff --git a/data/shaders/tex/edge_white_mbu.spec.jpg b/data/shaders/tex/edge_white_mbu.spec.jpg new file mode 100644 index 00000000..711711e3 Binary files /dev/null and b/data/shaders/tex/edge_white_mbu.spec.jpg differ diff --git a/data/shaders/tex/friction_high_mbu.normal.png b/data/shaders/tex/friction_high_mbu.normal.png new file mode 100644 index 00000000..d5c90c17 Binary files /dev/null and b/data/shaders/tex/friction_high_mbu.normal.png differ diff --git a/data/shaders/tex/friction_high_mbu.png b/data/shaders/tex/friction_high_mbu.png new file mode 100644 index 00000000..a6d478f2 Binary files /dev/null and b/data/shaders/tex/friction_high_mbu.png differ diff --git a/data/shaders/tex/friction_high_mbu.spec.png b/data/shaders/tex/friction_high_mbu.spec.png new file mode 100644 index 00000000..1608dfd1 Binary files /dev/null and b/data/shaders/tex/friction_high_mbu.spec.png differ diff --git a/data/shaders/tex/friction_high_shadow_mbu.png b/data/shaders/tex/friction_high_shadow_mbu.png new file mode 100644 index 00000000..4920a2a2 Binary files /dev/null and b/data/shaders/tex/friction_high_shadow_mbu.png differ diff --git a/data/shaders/tex/friction_low_mbu.normal.png b/data/shaders/tex/friction_low_mbu.normal.png new file mode 100644 index 00000000..46255fc0 Binary files /dev/null and b/data/shaders/tex/friction_low_mbu.normal.png differ diff --git a/data/shaders/tex/friction_low_mbu.spec.png b/data/shaders/tex/friction_low_mbu.spec.png new file mode 100644 index 00000000..4fb5d77f Binary files /dev/null and b/data/shaders/tex/friction_low_mbu.spec.png differ diff --git a/data/shaders/tex/noise.jpg b/data/shaders/tex/noise.jpg new file mode 100644 index 00000000..773883bf Binary files /dev/null and b/data/shaders/tex/noise.jpg differ diff --git a/data/shaders/tex/noise4.jpg b/data/shaders/tex/noise4.jpg new file mode 100644 index 00000000..7768981a Binary files /dev/null and b/data/shaders/tex/noise4.jpg differ diff --git a/data/shaders/tex/noise_blue.jpg b/data/shaders/tex/noise_blue.jpg new file mode 100644 index 00000000..e99e7f40 Binary files /dev/null and b/data/shaders/tex/noise_blue.jpg differ diff --git a/data/shaders/tex/noise_blue_shadow.jpg b/data/shaders/tex/noise_blue_shadow.jpg new file mode 100644 index 00000000..ad1f69ed Binary files /dev/null and b/data/shaders/tex/noise_blue_shadow.jpg differ diff --git a/data/shaders/tex/noise_green.jpg b/data/shaders/tex/noise_green.jpg new file mode 100644 index 00000000..015a6a88 Binary files /dev/null and b/data/shaders/tex/noise_green.jpg differ diff --git a/data/shaders/tex/noise_green_shadow.jpg b/data/shaders/tex/noise_green_shadow.jpg new file mode 100644 index 00000000..e405584f Binary files /dev/null and b/data/shaders/tex/noise_green_shadow.jpg differ diff --git a/data/shaders/tex/noise_red.jpg b/data/shaders/tex/noise_red.jpg new file mode 100644 index 00000000..b3841b96 Binary files /dev/null and b/data/shaders/tex/noise_red.jpg differ diff --git a/data/shaders/tex/noise_red_shadow.jpg b/data/shaders/tex/noise_red_shadow.jpg new file mode 100644 index 00000000..feb37dfa Binary files /dev/null and b/data/shaders/tex/noise_red_shadow.jpg differ diff --git a/data/shaders/tex/noise_shadow.jpg b/data/shaders/tex/noise_shadow.jpg new file mode 100644 index 00000000..a2443e02 Binary files /dev/null and b/data/shaders/tex/noise_shadow.jpg differ diff --git a/data/shaders/tex/plate_mbu.normal.png b/data/shaders/tex/plate_mbu.normal.png new file mode 100644 index 00000000..4e346960 Binary files /dev/null and b/data/shaders/tex/plate_mbu.normal.png differ diff --git a/data/shaders/tex/plate_mbu.spec.jpg b/data/shaders/tex/plate_mbu.spec.jpg new file mode 100644 index 00000000..0882c735 Binary files /dev/null and b/data/shaders/tex/plate_mbu.spec.jpg differ diff --git a/data/shaders/tex/tile_mbu.normal.png b/data/shaders/tex/tile_mbu.normal.png new file mode 100644 index 00000000..b3a15cdc Binary files /dev/null and b/data/shaders/tex/tile_mbu.normal.png differ diff --git a/data/shaders/tex/tile_mbu.spec.jpg b/data/shaders/tex/tile_mbu.spec.jpg new file mode 100644 index 00000000..711711e3 Binary files /dev/null and b/data/shaders/tex/tile_mbu.spec.jpg differ diff --git a/data/shaders/tex/wall_mbu.normal.png b/data/shaders/tex/wall_mbu.normal.png new file mode 100644 index 00000000..2f0f6bbc Binary files /dev/null and b/data/shaders/tex/wall_mbu.normal.png differ diff --git a/data/shaders/tex/wall_mbu.spec.png b/data/shaders/tex/wall_mbu.spec.png new file mode 100644 index 00000000..52530143 Binary files /dev/null and b/data/shaders/tex/wall_mbu.spec.png differ diff --git a/src/DifBuilder.hx b/src/DifBuilder.hx index ab48cc04..fe34ac20 100644 --- a/src/DifBuilder.hx +++ b/src/DifBuilder.hx @@ -1,5 +1,9 @@ package src; +import shaders.NormalMaterial; +import shaders.NoiseTileMaterial; +import shaders.DirLight; +import shaders.PhongMaterial; import dif.Edge; import h3d.shader.pbr.PropsValues; import h3d.mat.Material; @@ -25,6 +29,7 @@ import h3d.prim.BigPrimitive; import dif.Interior; import dif.Dif; import src.InteriorObject; +import src.MarbleGame; import src.ResourceLoaderWorker; class DifBuilderTriangle { @@ -167,6 +172,96 @@ class DifBuilder { } ]; + static function createPhongMaterial(onFinish:hxsl.Shader->Void, baseTexture:String, specTexture:String, normalTexture:String, shininess:Float, + specularIntensity:Float, secMapUVFactor:Float = 1) { + var worker = new ResourceLoaderWorker(() -> { + var diffuseTex = ResourceLoader.getTexture('data/interiors_mbu/${baseTexture}').resource; + var specularTex = ResourceLoader.getTexture('data/shaders/tex/${specTexture}').resource; + specularTex.wrap = Repeat; + var normalTex = ResourceLoader.getTexture('data/shaders/tex/${normalTexture}').resource; + normalTex.wrap = Repeat; + var shader = new PhongMaterial(diffuseTex, specularTex, normalTex, shininess, specularIntensity, MarbleGame.instance.world.ambient, + MarbleGame.instance.world.dirLight, MarbleGame.instance.world.dirLightDir, secMapUVFactor); + onFinish(shader); + }); + worker.loadFile('interiors_mbu/${baseTexture}'); + worker.loadFile('shaders/tex/${specTexture}'); + worker.loadFile('shaders/tex/${normalTexture}'); + worker.run(); + } + + static function createNoiseTileMaterial(onFinish:hxsl.Shader->Void, baseTexture:String, noiseSuffix:String) { + var worker = new ResourceLoaderWorker(() -> { + var diffuseTex = ResourceLoader.getTexture('data/interiors_mbu/${baseTexture}').resource; + var specularTex = ResourceLoader.getTexture('data/shaders/tex/tile_mbu.spec.jpg').resource; + specularTex.wrap = Repeat; + var normalTex = ResourceLoader.getTexture('data/shaders/tex/tile_mbu.normal.png').resource; + normalTex.wrap = Repeat; + var noiseTex = ResourceLoader.getTexture('data/shaders/tex/noise${noiseSuffix}.jpg').resource; + var shader = new NoiseTileMaterial(diffuseTex, specularTex, normalTex, noiseTex, 40, 0.7, MarbleGame.instance.world.ambient, + MarbleGame.instance.world.dirLight, MarbleGame.instance.world.dirLightDir, 1); + onFinish(shader); + }); + worker.loadFile('interiors_mbu/${baseTexture}'); + worker.loadFile('shaders/tex/noise${noiseSuffix}.jpg'); + worker.loadFile('shaders/tex/tile_mbu.spec.jpg'); + worker.loadFile('shaders/tex/tile_mbu.normal.png'); + worker.run(); + } + + static function createNormalMapMaterial(onFinish:hxsl.Shader->Void, baseTexture:String, normalTexture:String) { + var worker = new ResourceLoaderWorker(() -> { + var diffuseTex = ResourceLoader.getTexture('data/interiors_mbu/${baseTexture}').resource; + var normalTex = ResourceLoader.getTexture('data/shaders/tex/${normalTexture}').resource; + normalTex.wrap = Repeat; + var shader = new NormalMaterial(diffuseTex, normalTex, MarbleGame.instance.world.ambient, MarbleGame.instance.world.dirLight, + MarbleGame.instance.world.dirLightDir); + onFinish(shader); + }); + worker.loadFile('interiors_mbu/${baseTexture}'); + worker.loadFile('shaders/tex/${normalTexture}'); + worker.run(); + } + + static var shaderMaterialDict:MapVoid)->Void> = [ + 'interiors_mbu/plate_1.jpg' => (onFinish) -> createPhongMaterial(onFinish, 'plate_1.jpg', 'plate_mbu.spec.jpg', 'plate_mbu.normal.png', 30, 0.5), + 'interiors_mbu/tile_beginner.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_beginner.png', ''), + 'interiors_mbu/tile_beginner_shadow.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_beginner_shadow.png', ''), + 'interiors_mbu/tile_beginner_red.jpg' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_beginner_red.jpg', ''), + 'interiors_mbu/tile_beginner_red_shadow.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_beginner_red_shadow.png', ''), + 'interiors_mbu/tile_beginner_blue.jpg' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_beginner_blue.jpg', ''), + 'interiors_mbu/tile_beginner_blue_shadow.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_beginner_blue_shadow.png', ''), + 'interiors_mbu/tile_intermediate.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_intermediate.png', ''), + 'interiors_mbu/tile_intermediate_shadow.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_intermediate_shadow.png', ''), + 'interiors_mbu/tile_intermediate_red.jpg' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_intermediate_red.jpg', ''), + 'interiors_mbu/tile_intermediate_red_shadow.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_intermediate_red_shadow.png', ''), + 'interiors_mbu/tile_intermediate_green.jpg' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_intermediate_green.jpg', ''), + 'interiors_mbu/tile_intermediate_green_shadow.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_intermediate_green_shadow.png', ''), + 'interiors_mbu/tile_advanced.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_advanced.png', ''), + 'interiors_mbu/tile_advanced_shadow.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_advanced_shadow.png', ''), + 'interiors_mbu/tile_advanced_blue.jpg' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_advanced_blue.jpg', ''), + 'interiors_mbu/tile_advanced_blue_shadow.png' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_advanced_blue_shadow.png', ''), + 'interiors_mbu/tile_advanced_green.jpg' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_advanced_green.jpg', ''), + 'interiors_mbu/tile_advanced_green_shadow.jpg' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_advanced_green_shadow.png', ''), + 'interiors_mbu/tile_underside.jpg' => (onFinish) -> createNoiseTileMaterial(onFinish, 'tile_underside.jpg', ''), + 'interiors_mbu/wall_beginner.png' => (onFinish) -> createPhongMaterial(onFinish, 'wall_beginner.png', 'wall_mbu.spec.png', 'wall_mbu.normal.png', 30, + 0.5), + 'interiors_mbu/edge_white.jpg' => (onFinish) -> createPhongMaterial(onFinish, 'edge_white.jpg', 'edge_white_mbu.spec.jpg', + 'edge_white_mbu.normal.jpg', 50, 4), + 'interiors_mbu/edge_white_shadow.png' => (onFinish) -> createPhongMaterial(onFinish, 'edge_white_shadow.png', 'edge_white_mbu.spec.jpg', + 'edge_white_mbu.normal.jpg', 50, 4), + 'interiors_mbu/beam.png' => (onFinish) -> createNormalMapMaterial(onFinish, 'beam.png', 'beam_side_mbu.normal.png'), + 'interiors_mbu/beam_side.png' => (onFinish) -> createNormalMapMaterial(onFinish, 'beam_side.png', 'beam_side_mbu.normal.png'), + 'interiors_mbu/friction_low.jpg' => (onFinish) -> createPhongMaterial(onFinish, 'friction_low.jpg', 'friction_low_mbu.spec.png', + 'friction_low_mbu.normal.png', 100, 3), + 'interiors_mbu/friction_low_shadow.png' => (onFinish) -> createPhongMaterial(onFinish, 'friction_low_shadow.png', 'friction_low_mbu.spec.png', + 'friction_low_mbu.normal.png', 100, 3), + 'interiors_mbu/friction_high.png' => (onFinish) -> createPhongMaterial(onFinish, 'friction_high.png', 'friction_high_mbu.spec.png', + 'friction_high_mbu.normal.png', 30, 0.8, 2), + 'interiors_mbu/friction_high_shadow.png' => (onFinish) -> createPhongMaterial(onFinish, 'friction_high_shadow.png', 'friction_high_mbu.spec.png', + 'friction_high_mbu.normal.png', 30, 0.8, 2) + ]; + public static function loadDif(path:String, itr:InteriorObject, onFinish:Void->Void, ?so:Int = -1) { #if (js || android) path = StringTools.replace(path, "data/", ""); @@ -558,6 +653,11 @@ class DifBuilder { } } var worker = new ResourceLoaderWorker(() -> { + var shaderWorker = new ResourceLoaderWorker(() -> { + difresource.release(); + onFinish(); + }); + for (grp => tris in mats) { var points = []; var normals = []; @@ -591,18 +691,38 @@ class DifBuilder { texture = ResourceLoader.getFileEntry(tex(grp)).toImage().toTexture(); texture.wrap = Wrap.Repeat; texture.mipMap = Nearest; + var exactName = StringTools.replace(texture.name, "data/", ""); material = h3d.mat.Material.create(texture); + if (shaderMaterialDict.exists(exactName)) { + var retrievefunc = shaderMaterialDict[exactName]; + shaderWorker.addTask(fwd -> { + retrievefunc(shad -> { + material.mainPass.removeShader(material.textureShader); + material.mainPass.addShader(shad); + material.receiveShadows = true; + var thisprops:Dynamic = material.getDefaultProps(); + thisprops.light = false; // We will calculate our own lighting + material.props = thisprops; + material.shadows = false; + fwd(); + }); + }); + prim.addTangents(); + } else { + material.shadows = false; + material.receiveShadows = true; + } } else { material = Material.create(); + material.shadows = false; + material.receiveShadows = true; } - material.shadows = false; - material.receiveShadows = true; // material.mainPass.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1)); // material.mainPass.wireframe = true; var mesh = new Mesh(prim, material, itr); } - difresource.release(); - onFinish(); + + shaderWorker.run(); }); for (f in loadtexs) { worker.loadFile(f); diff --git a/src/InstanceManager.hx b/src/InstanceManager.hx index 76d511b2..0d5fe1ef 100644 --- a/src/InstanceManager.hx +++ b/src/InstanceManager.hx @@ -1,5 +1,8 @@ package src; +import shaders.NormalMaterial; +import shaders.NoiseTileMaterial; +import shaders.PhongMaterial; import h3d.prim.Instanced; import h3d.shader.pbr.PropsValues; import shaders.Billboard; @@ -129,6 +132,24 @@ class InstanceManager { minfo.meshbatch.material.mainPass.addShader(dtsshader); // minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; } + 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; + } minfo.transparencymeshbatch = new MeshBatch(cast(cast(obj, Mesh).primitive), cast(cast(obj, Mesh)).material.clone(), scene); minfo.transparencymeshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader); minfo.transparencymeshbatch.material.mainPass.addShader(dtsshader); diff --git a/src/Marble.hx b/src/Marble.hx index e600bbab..ad1e0fc6 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -856,11 +856,15 @@ class Marble extends GameObject { slipVolume = 0; if (time.currentAttemptTime - this.megaMarbleEnableTime < 10) { - rollMegaSound.volume = rollVolume; - rollSound.volume = 0; + if (this.rollMegaSound != null) { + rollMegaSound.volume = rollVolume; + rollSound.volume = 0; + } } else { rollSound.volume = rollVolume; - rollMegaSound.volume = 0; + if (this.rollMegaSound != null) { + rollMegaSound.volume = 0; + } } slipSound.volume = slipVolume; diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index a2164c80..5351a943 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -113,9 +113,13 @@ class MarbleWorld extends Scheduler { var endPadElement:MissionElementStaticShape; var endPad:EndPad; - var skyElement:MissionElementSky; + // Lighting + public var ambient:Vector; + public var dirLight:Vector; + public var dirLightDir:Vector; + public var scene:Scene; public var scene2d:h2d.Scene; public var mission:Mission; @@ -277,6 +281,8 @@ class MarbleWorld extends Scheduler { var ls = cast(scene.lightSystem, h3d.scene.fwd.LightSystem); ls.ambientLight.load(ambientColor); + this.ambient = ambientColor; + // ls.perPixelLighting = false; var shadow = scene.renderer.getPass(h3d.pass.DefaultShadowMap); shadow.power = 0.5; @@ -287,6 +293,9 @@ class MarbleWorld extends Scheduler { var sunlight = new DirLight(sunDirection, scene); sunlight.color = directionalColor; + + this.dirLight = directionalColor; + this.dirLightDir = sunDirection; } onFinish(); @@ -332,6 +341,7 @@ class MarbleWorld extends Scheduler { "sound/bumperding1.wav", "sound/bumper1.wav", "sound/jump.wav", + "sound/mega_roll.wav", "sound/bouncehard1.wav", "sound/bouncehard2.wav", "sound/bouncehard3.wav", diff --git a/src/gui/PlayMissionGui.hx b/src/gui/PlayMissionGui.hx index f56eaff8..29172e88 100644 --- a/src/gui/PlayMissionGui.hx +++ b/src/gui/PlayMissionGui.hx @@ -745,7 +745,7 @@ class PlayMissionGui extends GuiImage { @:privateAccess pmDifficulty.anim.frames = loadButtonImages('data/ui/play/difficulty_${category}'); pmDifficultyMarble.bmp.tile = ResourceLoader.getResource('data/ui/play/marble_${game}.png', ResourceLoader.getImage, this.imageResources).toTile(); - if (game == "platinum" || game == "ultra") { + if (game == "platinum") { pmAchievements.disabled = false; } else { pmAchievements.disabled = true; diff --git a/src/shaders/DirLight.hx b/src/shaders/DirLight.hx index d4a46e4f..80cb947c 100644 --- a/src/shaders/DirLight.hx +++ b/src/shaders/DirLight.hx @@ -5,10 +5,13 @@ import h3d.scene.fwd.Light; class DirLight extends Light { var dshader:DirLightShader; + public var direction:h3d.Vector; + public function new(?dir:h3d.Vector, ?parent) { dshader = new DirLightShader(); super(dshader, parent); priority = 100; + direction = dir; if (dir != null) setDirection(dir); } diff --git a/src/shaders/NoiseTileMaterial.hx b/src/shaders/NoiseTileMaterial.hx new file mode 100644 index 00000000..0bd2707d --- /dev/null +++ b/src/shaders/NoiseTileMaterial.hx @@ -0,0 +1,119 @@ +package shaders; + +class NoiseTileMaterial extends hxsl.Shader { + static var SRC = { + @param var diffuseMap:Sampler2D; + @param var specularMap:Sampler2D; + @param var normalMap:Sampler2D; + @param var noiseMap:Sampler2D; + @param var shininess:Float; + @param var specularIntensity:Float; + @param var ambientLight:Vec3; + @param var dirLight:Vec3; + @param var dirLightDir:Vec3; + @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 normal:Vec3; + var tangent:Vec3; + var uv:Vec2; + }; + var calculatedUV:Vec2; + var pixelColor:Vec4; + var specColor:Vec3; + var specPower:Float; + var transformedPosition:Vec3; + var transformedNormal:Vec3; + @var var transformedTangent:Vec4; + function __init__vertex() { + transformedTangent = vec4(input.tangent * global.modelView.mat3(), input.tangent.dot(input.tangent) > 0.5 ? 1. : -1.); + } + function lambert(normal:Vec3, lightPosition:Vec3):Float { + var result = dot(normal, lightPosition); + return max(result, 0.0); + } + function vertex() { + calculatedUV = input.uv; + } + function fragment() { + // Diffuse part + var diffuse = diffuseMap.get(calculatedUV); + + // noise + + var noiseIndex:Vec2; + var noiseColor1:Vec4; + var noiseColor2:Vec4; + var noiseColor3:Vec4; + var noiseColor4:Vec4; + var halfPixel = vec2(1.0 / 64.0, 1.0 / 64.0); + + noiseIndex.x = floor(calculatedUV.x - halfPixel.x) / 63.0 + 0.5 / 64.0; + noiseIndex.y = floor(calculatedUV.y - halfPixel.y) / 63.0 + 0.5 / 64.0; + noiseColor1 = noiseMap.get(noiseIndex) * 1.0 - 0.5; + + noiseIndex.x = floor(calculatedUV.x - halfPixel.x) / 63.0 + 0.5 / 64.0; + noiseIndex.y = floor(calculatedUV.y + halfPixel.y) / 63.0 + 0.5 / 64.0; + noiseColor2 = noiseMap.get(noiseIndex) * 1.0 - 0.5; + + noiseIndex.x = floor(calculatedUV.x + halfPixel.x) / 63.0 + 0.5 / 64.0; + noiseIndex.y = floor(calculatedUV.y + halfPixel.y) / 63.0 + 0.5 / 64.0; + noiseColor3 = noiseMap.get(noiseIndex) * 1.0 - 0.5; + + noiseIndex.x = floor(calculatedUV.x + halfPixel.x) / 63.0 + 0.5 / 64.0; + noiseIndex.y = floor(calculatedUV.y - halfPixel.y) / 63.0 + 0.5 / 64.0; + noiseColor4 = noiseMap.get(noiseIndex) * 1.0 - 0.5; + + var finalNoiseCol = (noiseColor1 + noiseColor2 + noiseColor3 + noiseColor4) / 4.0; + diffuse.rgb *= 1.0 + finalNoiseCol.r; // This isn't how MBU does it afaik but it looks good :o + + var incomingLight = vec3(0.0); + var specularLight = vec3(0.0); + + incomingLight += ambientLight; + var n = transformedNormal; + var nf = unpackNormal(normalMap.get(calculatedUV * secondaryMapUvFactor)); + var tanX = transformedTangent.xyz.normalize(); + var tanY = n.cross(tanX) * -transformedTangent.w; + transformedNormal = (nf.x * tanX + nf.y * tanY + nf.z * n).normalize(); + + var addedLight = dirLight * lambert(transformedNormal, -dirLightDir); + incomingLight += addedLight; + + var viewDir = normalize(camera.position - transformedPosition.xyz); + var halfwayDir = normalize(-dirLightDir + camera.dir); // Blinn-Phong + + var spec = pow(max(dot(transformedNormal, halfwayDir), 0.0), shininess); + + spec *= specularMap.get(secondaryMapUvFactor * calculatedUV).r; + + specularLight += vec3(specularIntensity * spec); + + var shaded = diffuse * vec4(incomingLight, 1); + shaded.rgb += specularLight; + + pixelColor = shaded; + } + } + + public function new(diffuse, specular, normal, noise, shininess, specularIntensity, ambientLight, dirLight, dirLightDir, secondaryMapUvFactor) { + super(); + this.diffuseMap = diffuse; + this.specularMap = specular; + this.normalMap = normal; + this.noiseMap = noise; + this.shininess = shininess; + this.specularIntensity = specularIntensity; + this.ambientLight = ambientLight.clone(); + this.dirLight = dirLight.clone(); + this.dirLightDir = dirLightDir.clone(); + this.secondaryMapUvFactor = secondaryMapUvFactor; + } +} diff --git a/src/shaders/NormalMaterial.hx b/src/shaders/NormalMaterial.hx new file mode 100644 index 00000000..ac241d1f --- /dev/null +++ b/src/shaders/NormalMaterial.hx @@ -0,0 +1,71 @@ +package shaders; + +class NormalMaterial extends hxsl.Shader { + static var SRC = { + @param var diffuseMap:Sampler2D; + @param var normalMap:Sampler2D; + @param var ambientLight:Vec3; + @param var dirLight:Vec3; + @param var dirLightDir:Vec3; + @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 normal:Vec3; + var tangent:Vec3; + var uv:Vec2; + }; + var calculatedUV:Vec2; + var pixelColor:Vec4; + var specColor:Vec3; + var specPower:Float; + var transformedPosition:Vec3; + var transformedNormal:Vec3; + @var var transformedTangent:Vec4; + function __init__vertex() { + transformedTangent = vec4(input.tangent * global.modelView.mat3(), input.tangent.dot(input.tangent) > 0.5 ? 1. : -1.); + } + function lambert(normal:Vec3, lightPosition:Vec3):Float { + var result = dot(normal, lightPosition); + return max(result, 0.0); + } + function vertex() { + calculatedUV = input.uv; + } + function fragment() { + // Diffuse part + var diffuse = diffuseMap.get(calculatedUV); + + var incomingLight = vec3(0.0); + var specularLight = vec3(0.0); + + incomingLight += ambientLight; + var n = transformedNormal; + var nf = unpackNormal(normalMap.get(calculatedUV)); + var tanX = transformedTangent.xyz.normalize(); + var tanY = n.cross(tanX) * -transformedTangent.w; + transformedNormal = (nf.x * tanX + nf.y * tanY + nf.z * n).normalize(); + + var addedLight = dirLight * lambert(transformedNormal, -dirLightDir); + incomingLight += addedLight; + + var shaded = diffuse * vec4(incomingLight, 1); + + pixelColor = shaded; + } + } + + public function new(diffuse, normal, ambientLight, dirLight, dirLightDir) { + super(); + this.diffuseMap = diffuse; + this.normalMap = normal; + this.ambientLight = ambientLight.clone(); + this.dirLight = dirLight.clone(); + this.dirLightDir = dirLightDir.clone(); + } +} diff --git a/src/shaders/PhongMaterial.hx b/src/shaders/PhongMaterial.hx new file mode 100644 index 00000000..cc62cad2 --- /dev/null +++ b/src/shaders/PhongMaterial.hx @@ -0,0 +1,89 @@ +package shaders; + +class PhongMaterial extends hxsl.Shader { + static var SRC = { + @param var diffuseMap:Sampler2D; + @param var specularMap:Sampler2D; + @param var normalMap:Sampler2D; + @param var shininess:Float; + @param var specularIntensity:Float; + @param var ambientLight:Vec3; + @param var dirLight:Vec3; + @param var dirLightDir:Vec3; + @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 normal:Vec3; + var tangent:Vec3; + var uv:Vec2; + }; + var calculatedUV:Vec2; + var pixelColor:Vec4; + var specColor:Vec3; + var specPower:Float; + var transformedPosition:Vec3; + var transformedNormal:Vec3; + @var var transformedTangent:Vec4; + function __init__vertex() { + transformedTangent = vec4(input.tangent * global.modelView.mat3(), input.tangent.dot(input.tangent) > 0.5 ? 1. : -1.); + } + function lambert(normal:Vec3, lightPosition:Vec3):Float { + var result = dot(normal, lightPosition); + return max(result, 0.0); + } + function vertex() { + calculatedUV = input.uv; + } + function fragment() { + // Diffuse part + var diffuse = diffuseMap.get(calculatedUV); + + var incomingLight = vec3(0.0); + var specularLight = vec3(0.0); + + incomingLight += ambientLight; + var n = transformedNormal; + var nf = unpackNormal(normalMap.get(calculatedUV * secondaryMapUvFactor)); + var tanX = transformedTangent.xyz.normalize(); + var tanY = n.cross(tanX) * -transformedTangent.w; + transformedNormal = (nf.x * tanX + nf.y * tanY + nf.z * n).normalize(); + + var addedLight = dirLight * lambert(transformedNormal, -dirLightDir); + incomingLight += addedLight; + + var viewDir = normalize(camera.position - transformedPosition.xyz); + var halfwayDir = normalize(-dirLightDir + camera.dir); // Blinn-Phong + + var spec = pow(max(dot(transformedNormal, halfwayDir), 0.0), shininess); + + spec *= specularMap.get(secondaryMapUvFactor * calculatedUV).r; + + specularLight += vec3(specularIntensity * spec); + + var shaded = diffuse * vec4(incomingLight, 1); + shaded.rgb += specularLight; + + pixelColor = shaded; + } + } + + public function new(diffuse, specular, normal, shininess, specularIntensity, ambientLight, dirLight, dirLightDir, secondaryMapUvFactor) { + super(); + this.diffuseMap = diffuse; + this.specularMap = specular; + this.normalMap = normal; + this.shininess = shininess; + this.specularIntensity = specularIntensity; + this.ambientLight = ambientLight.clone(); + this.dirLight = dirLight.clone(); + this.dirLightDir = dirLightDir.clone(); + this.secondaryMapUvFactor = secondaryMapUvFactor; + } +}