normalBitmapTexture.styleProperty = BasicStyle.NORMAL_MULTIPLIER;
specularBitmapTexture.styleProperty = BasicStyle.DIFFUSE_MULTIPLIER;
I believe this is because BasicStyle.DIFFUSE_MULTIPLIER is not the correct way to mark my specular map, but I do not know.
public final class BumpMappingStyle
{
// the style that will be used for the bump map texture
public static const BUMP_MAP : int = Style.getStyleId("bump map");
// an optional value to scale the bump effect
public static const BUMP_MULTIPLIER : int = Style.getStyleId("bump multiplier");
}
public class Main extends Sprite
{
private var _viewport : Viewport = new Viewport();
private var _camera : ArcBallCamera = new ArcBallCamera();
private var _scene : Group = new Group(_camera);
public function Main()
{
var bumpMap : BitmapTexture = LoaderGroup.loadClass(EMBED_BUMP)[0];
var diffuseMap : BitmapTexture = LoaderGroup.loadClass(EMBED_DIFFUSE)[0];
bumpMap.styleProperty = BumpMappingStyle.BUMP_MAP;
// useless because "ITexture.styleProperty" is set to BasicStyle.DIFFUSE by default :
// diffuseMap.styleProperty = BasicStyle.DIFFUSE;
var materialScene : MaterialGroup = new MaterialGroup(new SinglePassRenderingEffect(new BumpMappingShader()));
materialScene.textures.addChild(bumpMap).addChild(diffuseMap);
materialScene.addChild(CubeMesh.cubeMesh);
_scene.addChild(materialScene);
stage.addChild(_viewport);
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(event : Event) : void
{
_viewport.render(_scene);
}
}
public final class BumpMappingShader
{
override protected function getOutputPosition() : SValue
{
return vertexClipspacePosition;
}
override protected function getOutputColor() : SValue
{
var uv : SValue = interpolate(vertexUV);
// IMPORTANT: note that we sample BumpMappingStyle.BUMP_MAP
// sampling BumpMappingStyle.BUMP_MULTIPLIER does not make sense: it is supposed
// to be a scalar value
var bump : SValue = sampleTexture(BumpMappingStyle.BUMP_MAP, uv);
var diffuse : SValue = sampleTexture(BasicStyle.DIFFUSE, uv);
// do your bump mapping stuff here...
return bumpMappedDiffuse;
}
}
- Specular Maps do not work. When I run I get the error...
Error #3645: AGAL validation failed: Attribute registers can only be read in vertex programs for source operand 2 at token 2 of fragment program.
override protected function getOutputColor() : SValue
{
// vertexXXX values have to be interpolated because they are vertex attributes read in the VS
var vertexNormal : SValue = normalize(interpolate(vertexNormal));
// ...
}
The textures need to be added to a MaterialGroup, with an Effect, and this MaterialGroup is added to the Scene.
var matGroup : MaterialGroup = new MaterialGroup();
matGroup.textures.addChild(texture1).addChild(texture2);
matGroup.effect = new MyCoolEffect();
matGroup.style.set(MyCoolStyle.SOME_STYLE, someStyleValue);
Thanks a ton for all your hard work, Jean-Marc!
[Embed("../assets/Track_DF.png")]
private static const ASSET_DIFFUSE_MAP : Class;
private static const DIFFUSE_MAP_TEXTURE: ITexture = new LoaderGroup().loadClass(ASSET_DIFFUSE_MAP)[0] as ITexture;
[Embed("../assets/Track_NM.png")]
private static const ASSET_NORMAL_MAP : Class;
private var normalBitmapTexture: BitmapTexture = new LoaderGroup().loadClass(ASSET_NORMAL_MAP)[0];
private var NORMAL_MAP_TEXTURE: ITexture;
[Embed("../assets/Track_SP.png")]
private static const ASSET_SPECULAR_MAP : Class;
private var specularBitmapTexture : BitmapTexture = new LoaderGroup().loadClass(ASSET_SPECULAR_MAP)[0];
private var SPECULAR_MAP_TEXTURE : ITexture;
private var _camera : FirstPersonCamera = new FirstPersonCamera();
private var _spotlight : SpotLight = new SpotLight(0xffffff, 1., .8, 64, new Vector4(900., 500., 0.), 900., new Vector4(0., -1., 0.), .4, .4, 1024);
private var _scene : StyleGroup = new StyleGroup(_camera, _spotlight);
normalBitmapTexture.styleProperty = BasicStyle.NORMAL_MULTIPLIER;
NORMAL_MAP_TEXTURE = normalBitmapTexture as ITexture;
specularBitmapTexture.styleProperty = BasicStyle.DIFFUSE_MULTIPLIER;
SPECULAR_MAP_TEXTURE = specularBitmapTexture as ITexture;
_trackGroup = new MaterialGroup(new TrackEffect(), DIFFUSE_MAP_TEXTURE, NORMAL_MAP_TEXTURE ,SPECULAR_MAP_TEXTURE);
_scene.addChild(_trackGroup);
public class TrackShader extends ActionScriptShader
{
private var _lightVec : SValue = null;
private var _eyeVec : SValue = null;
private var _halfVec : SValue = null;
override protected function getOutputPosition() : SValue
{
var vertexBitangent : SValue = cross(vertexNormal, vertexTangent);
var lightPosition : SValue = cameraLocalPosition;
var lightDirection : SValue = normalize(subtract(lightPosition, vertexPosition));
_lightVec = float3(
dotProduct3(lightDirection, vertexTangent),
dotProduct3(lightDirection, vertexBitangent),
dotProduct3(lightDirection, vertexNormal)
);
_eyeVec = normalize(subtract(vertexPosition, cameraLocalPosition));
_eyeVec = float3(
dotProduct3(_eyeVec, vertexTangent),
dotProduct3(_eyeVec, vertexBitangent),
dotProduct3(_eyeVec, vertexNormal)
);
var vertexPos : SValue = normalize(vertexPosition);
_halfVec = normalize(add(vertexPos, lightDirection));
_halfVec = float3(
dotProduct3(_halfVec, vertexTangent),
dotProduct3(_halfVec, vertexBitangent),
dotProduct3(_halfVec, vertexNormal)
);
return vertexClipspacePosition;
}
override protected function getOutputColor() : SValue
{
var pointLights:WorldDataList = getWorldDataList(LightData);
var numLights:int = pointLights.length;
var uv : SValue = interpolate(vertexUV);
var pos : SValue = interpolate(vertexPosition);
var normal : SValue = interpolate(vertexNormal);
var diffuseMapValue : SValue = sampleTexture(BasicStyle.DIFFUSE, uv);
var normalMapValue : SValue = sampleTexture(BasicStyle.NORMAL_MULTIPLIER, uv);
var normalVec : SValue = subtract(normalMapValue.multiply(2.),1.);
normalVec.normalize();
var specularMapValue : SValue = sampleTexture(BasicStyle.DIFFUSE_MULTIPLIER, uv);
var specularMapVectorHack : Vector4 = new Vector4(.5,.5,.5);
var illumination:SValue = float3(0.,0.,0.);
for (var lightIndex : int = 0; lightIndex < numLights; ++lightIndex)
{
var lightPosition : SValue = getWorldParameter(3, LightData, LightData.LOCAL_POSITION, lightIndex);
var lightDiffuse : SValue = getWorldParameter(3, LightData, LightData.PREMULTIPLIED_DIFFUSE_COLOR, lightIndex);
var squareLocalDist : SValue = getWorldParameter(1, LightData, LightData.SQUARE_LOCAL_DISTANCE, lightIndex);
var lightToPoint : SValue = subtract(pos, lightPosition);
//Specular test
// do I need these numbers? they are set in the light but not used in the specular illumination calculation
//var lightSpecular : SValue = getWorldParameter(1, LightData, LightData.PREMULTIPLIED_SPECULAR, lightIndex);
//var lightShininess : SValue = getWorldParameter(1, LightData, LightData.PREMULTIPLIED_SHININESS, lightIndex);
var lightPower : Number = 2.0; // power hard coded. can I get/set it in the pointLight objects?
var ref : SValue = getReflectedVector(_lightVec, normalVec);
var halfVector : SValue = interpolate(_halfVec);
var shininess : SValue = power(max(dotProduct3(ref, halfVector), 0.0), lightPower);
//illumination.increment(shininess.multiply(specularMapValue)); // what can I do to get this to work?
illumination.incrementBy(shininess.multiply(specularMapVectorHack));
// hacky hacky...
var attenuation : SValue = saturate(multiply(squareLocalDist,reciprocal(dotProduct3(lightToPoint, lightToPoint))));
// here goes the hack again...
lightDiffuse.scaleBy(attenuation).scaleBy(.8);
illumination.incrementBy(lightDiffuse);
}
return float4(multiply(diffuseMapValue.rgb, illumination), diffuseMapValue.a);
}
}
//illumination.increment(shininess.multiply(specularMapValue)); // what can I do to get this to work?
illumination.incrementBy(shininess.multiply(specularMapVectorHack));
illumination.incrementBy(shininess.multiply(specularMapVectorHack));
Issues with the shader...
- Normal Maps work (yay!).
override protected function getOutputColor() : SValue
{
var pointLights:WorldDataList = getWorldDataList(LightData);
var numLights:int = pointLights.length;
var uv : SValue = interpolate(vertexUV);
var pos : SValue = interpolate(vertexPosition);
var diffuseMapValue : SValue = sampleTexture(BasicStyle.DIFFUSE, uv);
var normalMapValue : SValue = sampleTexture(BasicStyle.NORMAL_MULTIPLIER, uv);
var normalVec : SValue = subtract(normalMapValue.multiply(2.0),1.0);
var illumination:SValue = float3(0.,0.,0.);
for (var lightIndex : int = 0; lightIndex < numLights; ++lightIndex)
{
var lightPosition : SValue = getWorldParameter(3, LightData, LightData.LOCAL_POSITION, lightIndex);
var lightToPoint : SValue = subtract(pos, lightPosition);
lightToPoint.normalize();
illumination.incrementBy( max(dotProduct3(lightToPoint,normalVec), 0.0));
}
return float4(multiply(diffuseMapValue.rgb, illumination), diffuseMapValue.a);
}
var normalMapValue : SValue = sampleTexture(BasicStyle.NORMAL_MULTIPLIER, uv);
public final class MyCoolEffectStyle
{
public static const NORMAL_MAP : int = Style.getStyle("my cool effect normal map");
}
public class MyCoolShader
{
override protected getOutputPosition() : SValue
{
return vertexClipspacePosition;
}
override protected getOutputColor() : SValue
{
var uv : SValue = interpolate(vertexUV);
var normalMapValue : SValue = sampleTexture(MyCoolStyle.NORMAL_MAP, uv);
// do your stuff...
}
}
I'm confused about the usage of BasicStyle.NORMAL_MULTIPLIER above. Did you make a typo? If I create a new StyleId (NORMAL_MAP), would I call sampleTexture(MyCoolEffectStyle.NORMAL_MAP, uv)?
I created new Style for my specular map, if I need to create another style for my normal map, that's fine.
Im realised own normal(bump) mapper shader with various lighting models, if you interested in it i can post some code there.
if you interested in it i can post some code
It looks like you're new here. If you want to get involved, click one of these buttons!