mbu materials finally

This commit is contained in:
RandomityGuy 2022-12-08 19:03:16 +05:30
parent d261a15cb2
commit 5c702d39e6
41 changed files with 451 additions and 10 deletions

6
.gitignore vendored
View file

@ -7,4 +7,8 @@ native
*.obj *.obj
settings.json settings.json
release release
Export Export
node_modules
fonts
package.json
package-lock.json

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

BIN
data/shaders/tex/noise.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
data/shaders/tex/noise4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View file

@ -1,5 +1,9 @@
package src; package src;
import shaders.NormalMaterial;
import shaders.NoiseTileMaterial;
import shaders.DirLight;
import shaders.PhongMaterial;
import dif.Edge; import dif.Edge;
import h3d.shader.pbr.PropsValues; import h3d.shader.pbr.PropsValues;
import h3d.mat.Material; import h3d.mat.Material;
@ -25,6 +29,7 @@ import h3d.prim.BigPrimitive;
import dif.Interior; import dif.Interior;
import dif.Dif; import dif.Dif;
import src.InteriorObject; import src.InteriorObject;
import src.MarbleGame;
import src.ResourceLoaderWorker; import src.ResourceLoaderWorker;
class DifBuilderTriangle { 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:Map<String, (hxsl.Shader->Void)->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) { public static function loadDif(path:String, itr:InteriorObject, onFinish:Void->Void, ?so:Int = -1) {
#if (js || android) #if (js || android)
path = StringTools.replace(path, "data/", ""); path = StringTools.replace(path, "data/", "");
@ -558,6 +653,11 @@ class DifBuilder {
} }
} }
var worker = new ResourceLoaderWorker(() -> { var worker = new ResourceLoaderWorker(() -> {
var shaderWorker = new ResourceLoaderWorker(() -> {
difresource.release();
onFinish();
});
for (grp => tris in mats) { for (grp => tris in mats) {
var points = []; var points = [];
var normals = []; var normals = [];
@ -591,18 +691,38 @@ class DifBuilder {
texture = ResourceLoader.getFileEntry(tex(grp)).toImage().toTexture(); texture = ResourceLoader.getFileEntry(tex(grp)).toImage().toTexture();
texture.wrap = Wrap.Repeat; texture.wrap = Wrap.Repeat;
texture.mipMap = Nearest; texture.mipMap = Nearest;
var exactName = StringTools.replace(texture.name, "data/", "");
material = h3d.mat.Material.create(texture); 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 { } else {
material = Material.create(); 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.addShader(new h3d.shader.pbr.PropsValues(1, 0, 0, 1));
// material.mainPass.wireframe = true; // material.mainPass.wireframe = true;
var mesh = new Mesh(prim, material, itr); var mesh = new Mesh(prim, material, itr);
} }
difresource.release();
onFinish(); shaderWorker.run();
}); });
for (f in loadtexs) { for (f in loadtexs) {
worker.loadFile(f); worker.loadFile(f);

View file

@ -1,5 +1,8 @@
package src; package src;
import shaders.NormalMaterial;
import shaders.NoiseTileMaterial;
import shaders.PhongMaterial;
import h3d.prim.Instanced; import h3d.prim.Instanced;
import h3d.shader.pbr.PropsValues; import h3d.shader.pbr.PropsValues;
import shaders.Billboard; import shaders.Billboard;
@ -129,6 +132,24 @@ class InstanceManager {
minfo.meshbatch.material.mainPass.addShader(dtsshader); minfo.meshbatch.material.mainPass.addShader(dtsshader);
// minfo.meshbatch.material.mainPass.culling = mat.mainPass.culling; // 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 = 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.removeShader(minfo.meshbatch.material.textureShader);
minfo.transparencymeshbatch.material.mainPass.addShader(dtsshader); minfo.transparencymeshbatch.material.mainPass.addShader(dtsshader);

View file

@ -856,11 +856,15 @@ class Marble extends GameObject {
slipVolume = 0; slipVolume = 0;
if (time.currentAttemptTime - this.megaMarbleEnableTime < 10) { if (time.currentAttemptTime - this.megaMarbleEnableTime < 10) {
rollMegaSound.volume = rollVolume; if (this.rollMegaSound != null) {
rollSound.volume = 0; rollMegaSound.volume = rollVolume;
rollSound.volume = 0;
}
} else { } else {
rollSound.volume = rollVolume; rollSound.volume = rollVolume;
rollMegaSound.volume = 0; if (this.rollMegaSound != null) {
rollMegaSound.volume = 0;
}
} }
slipSound.volume = slipVolume; slipSound.volume = slipVolume;

View file

@ -113,9 +113,13 @@ class MarbleWorld extends Scheduler {
var endPadElement:MissionElementStaticShape; var endPadElement:MissionElementStaticShape;
var endPad:EndPad; var endPad:EndPad;
var skyElement:MissionElementSky; var skyElement:MissionElementSky;
// Lighting
public var ambient:Vector;
public var dirLight:Vector;
public var dirLightDir:Vector;
public var scene:Scene; public var scene:Scene;
public var scene2d:h2d.Scene; public var scene2d:h2d.Scene;
public var mission:Mission; public var mission:Mission;
@ -277,6 +281,8 @@ class MarbleWorld extends Scheduler {
var ls = cast(scene.lightSystem, h3d.scene.fwd.LightSystem); var ls = cast(scene.lightSystem, h3d.scene.fwd.LightSystem);
ls.ambientLight.load(ambientColor); ls.ambientLight.load(ambientColor);
this.ambient = ambientColor;
// ls.perPixelLighting = false;
var shadow = scene.renderer.getPass(h3d.pass.DefaultShadowMap); var shadow = scene.renderer.getPass(h3d.pass.DefaultShadowMap);
shadow.power = 0.5; shadow.power = 0.5;
@ -287,6 +293,9 @@ class MarbleWorld extends Scheduler {
var sunlight = new DirLight(sunDirection, scene); var sunlight = new DirLight(sunDirection, scene);
sunlight.color = directionalColor; sunlight.color = directionalColor;
this.dirLight = directionalColor;
this.dirLightDir = sunDirection;
} }
onFinish(); onFinish();
@ -332,6 +341,7 @@ class MarbleWorld extends Scheduler {
"sound/bumperding1.wav", "sound/bumperding1.wav",
"sound/bumper1.wav", "sound/bumper1.wav",
"sound/jump.wav", "sound/jump.wav",
"sound/mega_roll.wav",
"sound/bouncehard1.wav", "sound/bouncehard1.wav",
"sound/bouncehard2.wav", "sound/bouncehard2.wav",
"sound/bouncehard3.wav", "sound/bouncehard3.wav",

View file

@ -745,7 +745,7 @@ class PlayMissionGui extends GuiImage {
@:privateAccess pmDifficulty.anim.frames = loadButtonImages('data/ui/play/difficulty_${category}'); @: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(); 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; pmAchievements.disabled = false;
} else { } else {
pmAchievements.disabled = true; pmAchievements.disabled = true;

View file

@ -5,10 +5,13 @@ import h3d.scene.fwd.Light;
class DirLight extends Light { class DirLight extends Light {
var dshader:DirLightShader; var dshader:DirLightShader;
public var direction:h3d.Vector;
public function new(?dir:h3d.Vector, ?parent) { public function new(?dir:h3d.Vector, ?parent) {
dshader = new DirLightShader(); dshader = new DirLightShader();
super(dshader, parent); super(dshader, parent);
priority = 100; priority = 100;
direction = dir;
if (dir != null) if (dir != null)
setDirection(dir); setDirection(dir);
} }

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}