private void SetTechniqueType(TechniqueType value) { technique = value; switch (value) { case TechniqueType.Colored: shader.Effect.CurrentTechnique = techniqueColored; break; case TechniqueType.Textured: shader.Effect.CurrentTechnique = techniqueTextured; break; case TechniqueType.TexturedNormalMapping: shader.Effect.CurrentTechnique = techniqueTexturedNormalMapping; break; case TechniqueType.ColoredShadows: shader.effect.CurrentTechnique = techniqueColoredShadows; break; case TechniqueType.TexturedShadows: shader.Effect.CurrentTechnique = techniqueTexturedShadows; break; case TechniqueType.TexturedNormalMappingShadows: shader.Effect.CurrentTechnique = techniqueTexturedNormalMappingShadows; break; } }
public AffectEffectProperty(AffectEffect type, int skillId, int subSkillId, float hitRate, EffectTarget target, EffectNumbers effectNumbers, int[] intValue, float[] floatValue, bool useDrain, PowerType powerType, TechniqueType techniqueType, global::Attribute attribute, bool isMissThrough) { this._type = type; this.skillId = skillId; this.subSkillId = subSkillId; this.hitRate = hitRate; this._techniqueType = techniqueType; this._attribute = attribute; this.target = target; this._effectNumbers = effectNumbers; this._powerType = powerType; this._floatValue = floatValue; this._intValue = intValue; this.useDrain = useDrain; this.isMissThrough = isMissThrough; }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <returns></returns> protected abstract HighLevelGpuProgram CreateFragmentProgram( SM2Profile prof, Terrain terrain, TechniqueType tt );
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <returns></returns> protected virtual string GetFragmentProgramName( SM2Profile prof, Terrain terrain, TechniqueType tt ) { string progName = terrain.MaterialName + "/sm2/fp"; switch ( tt ) { case TechniqueType.HighLod: progName += "/hlod"; break; case TechniqueType.LowLod: progName += "/llod"; break; case TechniqueType.RenderCompositeMap: progName += "/comp"; break; } return progName; }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <returns></returns> protected override HighLevelGpuProgram CreateFragmentProgram( SM2Profile prof, Terrain terrain, TechniqueType tt ) { HighLevelGpuProgramManager mgr = HighLevelGpuProgramManager.Instance; string progName = GetFragmentProgramName( prof, terrain, tt ); var ret = (HighLevelGpuProgram)mgr.GetByName( progName ); if ( ret == null ) { ret = mgr.CreateProgram( progName, ResourceGroupManager.DefaultResourceGroupName, "cg", GpuProgramType.Fragment ); } else { ret.Unload(); } if ( prof.IsLayerNormalMappingEnabled || prof.IsLayerParallaxMappingEnabled ) { //ret.SetParam( "profiles", "ps_2_x fp40" ); ret.Properties[ "profiles" ] = "ps_2_x fp40"; } else { //ret.SetParam( "profiles", "ps_2_0 fp30" ); ret.Properties[ "profiles" ] = "ps_2_0 fp30"; } //ret.SetParam( "entry_point", "main_fp" ); ret.Properties[ "entry_point" ] = "main_fp"; return ret; }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="gpuparams"></param> public virtual void UpdateFpParams( SM2Profile prof, Terrain terrain, TechniqueType tt, GpuProgramParameters gpuparams ) { gpuparams.IgnoreMissingParameters = true; // TODO - parameterise this? var scaleBiasSpecular = new Vector4( 0.03f, -0.04f, 32, 1 ); gpuparams.SetNamedConstant( "scaleBiasSpecular", scaleBiasSpecular ); }
/// <summary> /// / /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="prog"></param> public virtual void DefaultFpParams( SM2Profile prof, Terrain terrain, TechniqueType tt, HighLevelGpuProgram prog ) { GpuProgramParameters gparams = prog.DefaultParameters; gparams.IgnoreMissingParameters = true; #if true gparams.SetNamedAutoConstant( "ambient", GpuProgramParameters.AutoConstantType.AmbientLightColor, 0 ); gparams.SetNamedAutoConstant( "lightPosObjSpace", GpuProgramParameters.AutoConstantType.LightPositionObjectSpace, 0 ); gparams.SetNamedAutoConstant( "lightDiffuseColor", GpuProgramParameters.AutoConstantType.LightDiffuseColor, 0 ); gparams.SetNamedAutoConstant( "lightSpecularColor", GpuProgramParameters.AutoConstantType.LightSpecularColor, 0 ); gparams.SetNamedAutoConstant( "eyePosObjSpace", GpuProgramParameters.AutoConstantType.CameraPositionObjectSpace, 0 ); #warning missing auto constant type "FogColor" //gparams.SetNamedAutoConstant("fogColor", GpuProgramParameters.AutoConstantType.FogParams, 0); #endif }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="source"></param> protected abstract void GenerateVpFooter( SM2Profile prof, Terrain terrain, TechniqueType tt, ref string source );
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <returns></returns> protected override HighLevelGpuProgram CreateFragmentProgram( SM2Profile prof, Terrain terrain, TechniqueType tt ) { HighLevelGpuProgramManager mgr = HighLevelGpuProgramManager.Instance; string progName = GetFragmentProgramName( prof, terrain, tt ); var ret = (HighLevelGpuProgram)mgr.GetByName( progName ); if ( ret == null ) { ret = mgr.CreateProgram( progName, ResourceGroupManager.DefaultResourceGroupName, "hlsl", GpuProgramType.Fragment ); } else { ret.Unload(); } #warning very high shader version //ret.SetParam( "target", "ps_3_0" ); //ret.SetParam( "entry_point", "main_fp" ); ret.Properties[ "target" ] = "ps_3_0"; ret.Properties[ "entry_point" ] = "main_fp"; return ret; }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="source"></param> protected override void GenerateFpFooter( SM2Profile prof, Terrain terrain, TechniqueType tt, ref string source ) { if ( tt == TechniqueType.LowLod ) { source += " outputCol.rgb = diffuse;\n"; } else { if ( terrain.IsGlobalColorMapEnabled && prof.IsGlobalColorMapEnabled ) { // sample colour map and apply to diffuse source += " diffuse *= tex2D(globalColorMap, uv).rgb;\n"; } if ( prof.IsLightMapEnabled ) { // sample lightmap source += " shadow = tex2D(lightMap, uv).r;\n"; } // diffuse lighting source += " outputCol.rgb += ambient * diffuse + litRes.y * lightDiffuseColor * diffuse * shadow;\n"; // specular default if ( !prof.IsLayerSpecularMappingEnabled ) { source += " specular = 1.0;\n"; } if ( tt == TechniqueType.RenderCompositeMap ) { // Raw specular is embedded in composite map alpha source += " outputCol.a = specular * shadow;\n"; } else { // Apply specular source += " outputCol.rgb += litRes.z * lightSpecularColor * specular * shadow;\n"; if ( prof.Parent.DebugLevel != 0 ) { source += " outputCol.rg += lodInfo.xy;\n"; } } } // Final return source += " return outputCol;\n" + "}\n"; }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="source"></param> protected override void GenerateVpFooter( SM2Profile prof, Terrain terrain, TechniqueType tt, ref string source ) { source += " oPos = mul(viewProjMatrix, worldPos);\n" + " oUV = uv.xy;\n" + "}\n"; }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="layer"></param> /// <param name="source"></param> protected override void GenerateFpLayer( SM2Profile prof, Terrain terrain, TechniqueType tt, uint layer, ref string source ) { uint uvIdx = layer/2; string uvChannels = layer%2 != 0 ? ".zw" : ".xy"; uint blendIdx = ( layer - 1 )/4; // generate UV source += " float2 uv" + layer + " = layerUV" + uvIdx + uvChannels + ";\n"; // calculate lighting here if normal mapping if ( prof.IsLayerNormalMappingEnabled ) { if ( prof.IsLayerParallaxMappingEnabled && tt != TechniqueType.RenderCompositeMap ) { // modify UV - note we have to sample an extra time source += " displacement = tex2D(normtex" + layer + ", uv" + layer + ").a\n" + " * scaleBiasSpecular.x + scaleBiasSpecular.y;\n"; source += " uv" + layer + " += TSeyeDir.xy * displacement;\n"; } // access TS normal map source += " TSnormal = expand(tex2D(normtex" + layer + ", uv" + layer + ")).rgb;\n"; source += " TShalfAngle = normalize(TSlightDir + TSeyeDir);\n"; source += " litResLayer = lit(dot(TSlightDir, TSnormal), dot(TShalfAngle, TSnormal), scaleBiasSpecular.z);\n"; if ( layer == 0 ) { source += " litRes = litResLayer;\n"; } else { source += " litRes = lerp(litRes, litResLayer, blendTexVal" + blendIdx + "." + GetChannel( layer - 1 ) + ");\n"; } } // sample diffuse texture source += " float4 diffuseSpecTex" + layer + " = tex2D(difftex" + layer + ", uv" + layer + ");\n"; // apply to common if ( layer == 0 ) { source += " diffuse = diffuseSpecTex0.rgb;\n"; if ( prof.IsLayerSpecularMappingEnabled ) { source += " specular = diffuseSpecTex0.a;\n"; } } else { source += " diffuse = lerp(diffuse, diffuseSpecTex" + layer + ".rgb, blendTexVal" + blendIdx + "." + GetChannel( layer - 1 ) + ");\n"; if ( prof.IsLayerSpecularMappingEnabled ) { source += " specular = lerp(specular, diffuseSpecTex" + layer + ".a, blendTexVal" + blendIdx + "." + GetChannel( layer - 1 ) + ");\n"; } } }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="layer"></param> /// <param name="source"></param> protected override void GenerateVpLayer( SM2Profile prof, Terrain terrain, TechniqueType tt, uint layer, ref string source ) { // nothing to do }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="source"></param> protected override void GenerateFpHeader( SM2Profile prof, Terrain terrain, TechniqueType tt, ref string source ) { // Main header source += // helpers "float4 expand(float4 v)\n" + "{ \n" + " return v * 2 - 1;\n" + "}\n\n\n" + "float4 main_fp(\n" + "float2 uv : TEXCOORD0,\n" + "float4 position : TEXCOORD1,\n"; // UV's premultiplied, packed as xy/zw uint maxLayers = prof.GetMaxLayers( terrain ); uint numBlendTextures = Utility.Min( terrain.GetBlendTextureCount( (byte)maxLayers ), terrain.GetBlendTextureCount() ); uint numLayers = Utility.Min( maxLayers, (uint)terrain.LayerCount ); uint numUVSets = numLayers/2; if ( numLayers%2 != 0 ) { ++numUVSets; } uint texCoordSet = 2; if ( tt != TechniqueType.LowLod ) { for ( uint i = 0; i < numUVSets; ++i ) { source += "float4 layerUV" + i + " : TEXCOORD" + texCoordSet++ + ", \n"; } } if ( prof.Parent.DebugLevel != 0 && tt != TechniqueType.RenderCompositeMap ) { source += "float2 lodInfo : TEXCOORD" + texCoordSet++ + ", \n"; } source += // Only 1 light supported in this version // deferred shading profile / generator later, ok? :) "uniform float4 ambient,\n" + "uniform float4 lightPosObjSpace,\n" + "uniform float3 lightDiffuseColor,\n" + "uniform float3 lightSpecularColor,\n" + "uniform float3 eyePosObjSpace,\n" + // pack scale, bias and specular "uniform float4 scaleBiasSpecular,\n"; if ( tt == TechniqueType.LowLod ) { // single composite map covers all the others below source += "uniform sampler2D compositeMap : register(s0)\n"; } else { source += "uniform sampler2D globalNormal : register(s0)\n"; uint currentSamplerIdx = 1; if ( terrain.IsGlobalColorMapEnabled && prof.IsGlobalColorMapEnabled ) { source += ", uniform sampler2D globalColorMap : register(s" + currentSamplerIdx++ + ")\n"; } if ( prof.IsLightMapEnabled ) { source += ", uniform sampler2D lightMap : register(s" + currentSamplerIdx++ + ")\n"; } // Blend textures - sampler definitions for ( uint i = 0; i < numBlendTextures; ++i ) { source += ", uniform sampler2D blendTex" + i + " : register(s" + currentSamplerIdx++ + ")\n"; } // Layer textures - sampler definitions & UV multipliers for ( uint i = 0; i < numLayers; ++i ) { source += ", uniform sampler2D difftex" + i + " : register(s" + currentSamplerIdx++ + ")\n"; source += ", uniform sampler2D normtex" + i + " : register(s" + currentSamplerIdx++ + ")\n"; } } source += ") : COLOR\n" + "{\n" + " float4 outputCol;\n" + " float shadow = 1.0;\n" + // base colour " outputCol = float4(0,0,0,1);\n"; if ( tt != TechniqueType.LowLod ) { source += // global normal " float3 normal = expand(tex2D(globalNormal, uv)).rgb;\n"; } source += " float3 lightDir = \n" + " lightPosObjSpace.xyz - (position.xyz * lightPosObjSpace.w);\n" + " float3 eyeDir = eyePosObjSpace - position.xyz;\n" + // set up accumulation areas " float3 diffuse = float3(0,0,0);\n" + " float specular = 0;\n"; if ( tt == TechniqueType.LowLod ) { // we just do a single calculation from composite map source += " float4 composite = tex2D(compositeMap, uv);\n" + " diffuse = composite.rgb;\n"; // TODO - specular; we'll need normals for this! } else { // set up the blend values for ( uint i = 0; i < numBlendTextures; ++i ) { source += " float4 blendTexVal" + i + " = tex2D(blendTex" + i + ", uv);\n"; } if ( prof.IsLayerNormalMappingEnabled ) { // derive the tangent space basis // we do this in the pixel shader because we don't have per-vertex normals // because of the LOD, we use a normal map // tangent is always +x or -z in object space depending on alignment switch ( terrain.Alignment ) { case Alignment.Align_X_Y: case Alignment.Align_X_Z: source += " float3 tangent = float3(1, 0, 0);\n"; break; case Alignment.Align_Y_Z: source += " float3 tangent = float3(0, 0, -1);\n"; break; } source += " float3 binormal = normalize(cross(tangent, normal));\n"; // note, now we need to re-cross to derive tangent again because it wasn't orthonormal source += " tangent = normalize(cross(normal, binormal));\n"; // derive final matrix source += " float3x3 TBN = float3x3(tangent, binormal, normal);\n"; // set up lighting result placeholders for interpolation source += " float4 litRes, litResLayer;\n"; source += " float3 TSlightDir, TSeyeDir, TShalfAngle, TSnormal;\n"; if ( prof.IsLayerParallaxMappingEnabled ) { source += " float displacement;\n"; } // move source += " TSlightDir = normalize(mul(TBN, lightDir));\n"; source += " TSeyeDir = normalize(mul(TBN, eyeDir));\n"; } else { // simple per-pixel lighting with no normal mapping source += " lightDir = normalize(lightDir);\n"; source += " eyeDir = normalize(eyeDir);\n"; source += " float3 halfAngle = normalize(lightDir + eyeDir);\n"; source += " float4 litRes = lit(dot(lightDir, normal), dot(halfAngle, normal), scaleBiasSpecular.z);\n"; } } }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="source"></param> protected virtual void GenerateFragmetProgramSource( SM2Profile prof, Terrain terrain, TechniqueType tt, ref string source ) { GenerateFpHeader( prof, terrain, tt, ref source ); if ( tt != TechniqueType.LowLod ) { uint maxLayers = prof.GetMaxLayers( terrain ); uint numLayers = Utility.Min( maxLayers, (uint)terrain.LayerCount ); for ( uint i = 0; i < numLayers; ++i ) { GenerateFpLayer( prof, terrain, tt, i, ref source ); } } GenerateFpFooter( prof, terrain, tt, ref source ); }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="source"></param> protected abstract void GenerateFpLayer( SM2Profile prof, Terrain terrain, TechniqueType tt, uint layer, ref string source );
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <returns></returns> protected override HighLevelGpuProgram CreateVertexProgram( SM2Profile prof, Terrain terrain, TechniqueType tt ) { HighLevelGpuProgramManager mgr = HighLevelGpuProgramManager.Instance; string progName = GetVertexProgramName( prof, terrain, tt ); switch ( tt ) { case TechniqueType.HighLod: progName += "/hlod"; break; case TechniqueType.LowLod: progName += "/llod"; break; case TechniqueType.RenderCompositeMap: progName += "/comp"; break; } var ret = (HighLevelGpuProgram)mgr.GetByName( progName ); if ( ret == null ) { ret = mgr.CreateProgram( progName, ResourceGroupManager.DefaultResourceGroupName, "glsl", GpuProgramType.Vertex ); } else { ret.Unload(); } return ret; }
/// <summary> /// / /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="prog"></param> public virtual void DefaultVpParams( SM2Profile prof, Terrain terrain, TechniqueType tt, HighLevelGpuProgram prog ) { GpuProgramParameters gparams = prog.DefaultParameters; gparams.IgnoreMissingParameters = true; gparams.SetNamedAutoConstant( "worldMatrix", GpuProgramParameters.AutoConstantType.WorldMatrix, 0 ); gparams.SetNamedAutoConstant( "viewProjMatrix", GpuProgramParameters.AutoConstantType.ViewProjMatrix, 0 ); gparams.SetNamedAutoConstant( "lodMorph", GpuProgramParameters.AutoConstantType.Custom, Terrain.LOD_MORPH_CUSTOM_PARAM ); gparams.SetNamedAutoConstant( "fogParams", GpuProgramParameters.AutoConstantType.FogParams, 0 ); }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <returns></returns> protected override HighLevelGpuProgram CreateFragmentProgram( SM2Profile prof, Terrain terrain, TechniqueType tt ) { HighLevelGpuProgramManager mgr = HighLevelGpuProgramManager.Instance; string progName = GetVertexProgramName( prof, terrain, tt ); var ret = (HighLevelGpuProgram)mgr.GetByName( progName ); if ( ret == null ) { ret = mgr.CreateProgram( progName, ResourceGroupManager.DefaultResourceGroupName, "glsl", GpuProgramType.Fragment ); } else { ret.Unload(); } return ret; }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="gpuparams"></param> public virtual void UpdateVpParams( SM2Profile prof, Terrain terrain, TechniqueType tt, GpuProgramParameters gpuparams ) { gpuparams.IgnoreMissingParameters = true; uint maxLayers = prof.GetMaxLayers( terrain ); uint numLayers = Utility.Min( maxLayers, (uint)terrain.LayerCount ); uint numUVMul = numLayers/4; if ( numUVMul%4 == 0 ) { ++numUVMul; } for ( uint i = 0; i < numUVMul; ++i ) { var uvMul = new Vector4( terrain.GetLayerUVMultiplier( (byte)( i*4 ) ), terrain.GetLayerUVMultiplier( (byte)( i*4 + 1 ) ), terrain.GetLayerUVMultiplier( (byte)( i*4 + 2 ) ), terrain.GetLayerUVMultiplier( (byte)( i*4 + 3 ) ) ); #if true gpuparams.SetNamedConstant( "uvMul" + i.ToString(), uvMul ); #endif } }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="source"></param> protected override void GenerateVpFooter( SM2Profile prof, Terrain terrain, TechniqueType tt, ref string source ) { //not implemted yet }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <returns></returns> protected override HighLevelGpuProgram CreateVertexProgram( SM2Profile prof, Terrain terrain, TechniqueType tt ) { HighLevelGpuProgramManager mgr = HighLevelGpuProgramManager.Instance; string progName = GetVertexProgramName( prof, terrain, tt ); var ret = (HighLevelGpuProgram)mgr.GetByName( progName ); if ( ret == null ) { ret = mgr.CreateProgram( progName, ResourceGroupManager.DefaultResourceGroupName, "cg", GpuProgramType.Vertex ); } else { ret.Unload(); } //ret.SetParam( "profiles", "vs_2_0 arbvp1" ); //ret.SetParam( "entry_point", "main_vp" ); ret.Properties[ "profiles" ] = "vs_2_0 arbvp1"; ret.Properties[ "entry_point" ] = "main_vp"; return ret; }
/// <summary> /// /// </summary> /// <param name="mat"></param> /// <param name="terrain"></param> /// <param name="tt"></param> protected void AddTechnique( Material mat, Terrain terrain, TechniqueType tt ) { string ttStr = string.Empty; switch ( tt ) { case TechniqueType.HighLod: ttStr += "hl"; break; case TechniqueType.LowLod: ttStr += "ll"; break; case TechniqueType.RenderCompositeMap: ttStr += "rc"; break; } LogManager.Instance.Write( "AddTechique:" + ttStr, null ); Technique tech = mat.CreateTechnique(); //only supporting one pass Pass pass = tech.CreatePass(); GpuProgramManager gmgr = GpuProgramManager.Instance; HighLevelGpuProgramManager hmgr = HighLevelGpuProgramManager.Instance; if ( this.mShaderGen == null ) { bool check2x = this.mLayerNormalMappingEnabled || this.mLayerParallaxMappingEnabled; /* if (hmgr.IsLanguageSupported("cg") && (check2x && (gmgr.IsSyntaxSupported("fp40") || gmgr.IsSyntaxSupported("ps_2_x"))) || (gmgr.IsSyntaxSupported("ps_2_0"))) mShaderGen = new ShaderHelperCG(); else*/ if ( hmgr.IsLanguageSupported( "hlsl" ) ) { this.mShaderGen = new ShaderHelperHLSL(); } else if ( hmgr.IsLanguageSupported( "glsl" ) ) { this.mShaderGen = new ShaderHelperGLSL(); } else { //TODO } } HighLevelGpuProgram vprog = this.mShaderGen.GenerateVertexProgram( this, terrain, tt ); HighLevelGpuProgram fprog = this.mShaderGen.GenerateFragmentProgram( this, terrain, tt ); pass.SetVertexProgram( vprog.Name ); pass.SetFragmentProgram( fprog.Name ); if ( tt == TechniqueType.HighLod || tt == TechniqueType.RenderCompositeMap ) { //global normal map TextureUnitState tu = pass.CreateTextureUnitState(); tu.SetTextureName( terrain.TerrainNormalMap.Name ); tu.SetTextureAddressingMode( TextureAddressing.Clamp ); //global color map if ( terrain.IsGlobalColorMapEnabled && IsGlobalColorMapEnabled ) { tu = pass.CreateTextureUnitState( terrain.GlobalColorMap.Name ); tu.SetTextureAddressingMode( TextureAddressing.Clamp ); } //light map if ( IsLightMapEnabled ) { tu = pass.CreateTextureUnitState( terrain.LightMap.Name ); tu.SetTextureAddressingMode( TextureAddressing.Clamp ); } //blend maps uint maxLayers = GetMaxLayers( terrain ); uint numBlendTextures = Utility.Min( terrain.GetBlendTextureCount( (byte)maxLayers ), terrain.GetBlendTextureCount() ); uint numLayers = Utility.Min( maxLayers, (uint)terrain.LayerCount ); for ( uint i = 0; i < numBlendTextures; ++i ) { tu = pass.CreateTextureUnitState( terrain.GetBlendTextureName( (byte)i ) ); tu.SetTextureAddressingMode( TextureAddressing.Clamp ); } //layer textures for ( uint i = 0; i < numLayers; ++i ) { //diffuse / specular string name = terrain.GetLayerTextureName( (byte)i, 0 ); tu = pass.CreateTextureUnitState( terrain.GetLayerTextureName( (byte)i, 0 ) ); //normal / height tu = pass.CreateTextureUnitState( terrain.GetLayerTextureName( (byte)i, 1 ) ); } } //end if else if ( this.mCompositeMapEnabled ) { // LOW_LOD textures // composite map TextureUnitState tu = pass.CreateTextureUnitState(); tu.SetTextureName( terrain.CompositeMap.Name ); tu.SetTextureAddressingMode( TextureAddressing.Clamp ); // That's it! } }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <param name="source"></param> protected override void GenerateVpHeader( SM2Profile prof, Terrain terrain, TechniqueType tt, ref string source ) { source += "void main_vp(\n" + "float4 pos : POSITION,\n" + "float2 uv : TEXCOORD0,\n"; if ( tt != TechniqueType.RenderCompositeMap ) { source += "float2 delta : TEXCOORD1,\n"; // lodDelta, lodThreshold } source += "uniform float4x4 worldMatrix,\n" + "uniform float4x4 viewProjMatrix,\n" + "uniform float2 lodMorph,\n"; // morph amount, morph LOD target // uv multipliers uint maxLayers = prof.GetMaxLayers( terrain ); uint numLayers = Utility.Min( maxLayers, (uint)terrain.LayerCount ); uint numUVMutipliers = ( numLayers/4 ); if ( numLayers%4 != 0 ) { ++numUVMutipliers; } for ( uint i = 0; i < numUVMutipliers; ++i ) { source += "uniform float4 uvMul" + i + ", \n"; } source += "out float4 oPos : POSITION,\n" + "out float2 oUV : TEXCOORD0, \n" + "out float4 oPosObj : TEXCOORD1 \n"; // layer UV's premultiplied, packed as xy/zw uint numUVSets = numLayers/2; if ( numLayers%2 != 0 ) { ++numUVSets; } uint texCoordSet = 2; if ( tt != TechniqueType.LowLod ) { for ( uint i = 0; i < numUVSets; ++i ) { source += ", out float4 oUV" + i + " : TEXCOORD" + texCoordSet++ + "\n"; } } if ( prof.Parent.DebugLevel != 0 && tt != TechniqueType.RenderCompositeMap ) { source += ", out float2 lodInfo : TEXCOORD" + texCoordSet++ + "\n"; } source += ")\n" + "{\n" + " float4 worldPos = mul(worldMatrix, pos);\n" + " oPosObj = pos;\n"; if ( tt != TechniqueType.RenderCompositeMap ) { // determine whether to apply the LOD morph to this vertex // we store the deltas against all vertices so we only want to apply // the morph to the ones which would disappear. The target LOD which is // being morphed to is stored in lodMorph.y, and the LOD at which // the vertex should be morphed is stored in uv.w. If we subtract // the former from the latter, and arrange to only morph if the // result is negative (it will only be -1 in fact, since after that // the vertex will never be indexed), we will achieve our aim. // sign(vertexLOD - targetLOD) == -1 is to morph source += " float toMorph = -min(0, sign(delta.y - lodMorph.y));\n"; // this will either be 1 (morph) or 0 (don't morph) if ( prof.Parent.DebugLevel != 0 ) { // x == LOD level (-1 since value is target level, we want to display actual) source += "lodInfo.x = (lodMorph.y - 1) / " + terrain.NumLodLevels + ";\n"; // y == LOD morph source += "lodInfo.y = toMorph * lodMorph.x;\n"; } //morph switch ( terrain.Alignment ) { case Alignment.Align_X_Y: break; case Alignment.Align_X_Z: source += " worldPos.y += delta.x * toMorph * lodMorph.x;\n"; break; case Alignment.Align_Y_Z: break; } } // generate UVs if ( tt == TechniqueType.LowLod ) { //passtrough source += " oUV = uv;\n"; } else { for ( uint i = 0; i < numUVSets; ++i ) { uint layer = i*2; uint uvMulIdx = layer/4; source += " oUV" + i + ".xy = " + " uv.xy * uvMul" + uvMulIdx + "." + GetChannel( layer ) + ";\n"; source += " oUV" + i + ".zw = " + " uv.xy * uvMul" + uvMulIdx + "." + GetChannel( layer + 1 ) + ";\n"; } } }
/// <summary> /// /// </summary> /// <param name="prof"></param> /// <param name="terrain"></param> /// <param name="tt"></param> /// <returns></returns> public virtual HighLevelGpuProgram GenerateFragmentProgram( SM2Profile prof, Terrain terrain, TechniqueType tt ) { HighLevelGpuProgram ret = CreateFragmentProgram( prof, terrain, tt ); string sourceStr = string.Empty; GenerateFragmetProgramSource( prof, terrain, tt, ref sourceStr ); ret.Source = sourceStr; DefaultFpParams( prof, terrain, tt, ret ); #if AXIOM_DEBUG_MODE LogManager.Instance.Write(LogMessageLevel.Trivial, false, "*** Terrain Fragment Program: " + ret.Name + " ***\n" + ret.Source + "\n*** ***"); #endif return ret; }