private void ResetStates() { for (int i = 0; i < Materials.Count; i++) { MaterialState State = States[i]; H3DMaterialParams Params = Materials[i].MaterialParams; State.Transforms[0] = Params.TextureCoords[0].GetTransform().ToMatrix4(); State.Transforms[1] = Params.TextureCoords[1].GetTransform().ToMatrix4(); State.Transforms[2] = Params.TextureCoords[2].GetTransform().ToMatrix4(); State.Emission = Params.EmissionColor.ToColor4(); State.Ambient = Params.AmbientColor.ToColor4(); State.Diffuse = Params.DiffuseColor.ToColor4(); State.Specular0 = Params.Specular0Color.ToColor4(); State.Specular1 = Params.Specular1Color.ToColor4(); State.Constant0 = Params.Constant0Color.ToColor4(); State.Constant1 = Params.Constant1Color.ToColor4(); State.Constant2 = Params.Constant2Color.ToColor4(); State.Constant3 = Params.Constant3Color.ToColor4(); State.Constant4 = Params.Constant4Color.ToColor4(); State.Constant5 = Params.Constant5Color.ToColor4(); State.Texture0Name = Materials[i].Texture0Name; State.Texture1Name = Materials[i].Texture1Name; State.Texture2Name = Materials[i].Texture2Name; } }
private static void SetConstantColor(int id, H3DMaterialParams mparams, RGBA target) { switch (id) { case 0: mparams.Constant0Color = target; break; case 1: mparams.Constant1Color = target; break; case 2: mparams.Constant2Color = target; break; case 3: mparams.Constant3Color = target; break; case 4: mparams.Constant4Color = target; break; case 5: mparams.Constant5Color = target; break; } }
public static uint GetTexEnvConfigHash(H3DMaterialParams Params) { FNV1a FNV = new FNV1a(); foreach (PICATexEnvStage Stage in Params.TexEnvStages) { FNV.Hash(Stage.Color.ToUInt32()); FNV.Hash(Stage.Combiner.ToUInt32()); FNV.Hash(Stage.Operand.ToUInt32()); FNV.Hash(Stage.Scale.ToUInt32()); FNV.Hash(Stage.Source.ToUInt32()); FNV.Hash(Stage.UpdateAlphaBuffer ? 1 : 0); FNV.Hash(Stage.UpdateColorBuffer ? 1 : 0); } FNV.Hash(Params.TexEnvBufferColor.ToUInt32()); return(FNV.HashCode); }
public FragmentShaderGenerator(H3DMaterialParams Params) { this.Params = Params; }
public void UpdateShaders() { DisposeShaders(); foreach (H3DMaterial Material in BaseModel.Materials) { H3DMaterialParams Params = Material.MaterialParams; int Hash = GetMaterialShaderHash(Params); bool HasHash = false; if (ShaderHashes.TryGetValue(Hash, out int ShaderIndex)) { HasHash = true; H3DMaterial m = BaseModel.Materials[ShaderIndex]; if (CompareMaterials(m.MaterialParams, Params)) { Shaders.Add(Shaders[ShaderIndex]); continue; } } if (!HasHash) { ShaderHashes.Add(Hash, Shaders.Count); } FragmentShaderGenerator FragShaderGen = new FragmentShaderGenerator(Params); int FragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader); Shader.CompileAndCheck(FragmentShaderHandle, FragShaderGen.GetFragShader()); VertexShader VtxShader = Renderer.GetShader(Params.ShaderReference); Shader Shdr = new Shader(FragmentShaderHandle, VtxShader); Shaders.Add(Shdr); GL.UseProgram(Shdr.Handle); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "Textures[0]"), 0); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "Textures[1]"), 1); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "Textures[2]"), 2); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "TextureCube"), 3); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "LUTs[0]"), 4); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "LUTs[1]"), 5); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "LUTs[2]"), 6); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "LUTs[3]"), 7); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "LUTs[4]"), 8); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, "LUTs[5]"), 9); for (int i = 0; i < 3; i++) { int j = i * 2; GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, $"LUTs[{6 + j}]"), 10 + j); GL.Uniform1(GL.GetUniformLocation(Shdr.Handle, $"LUTs[{7 + j}]"), 11 + j); } //Pokémon uses this Vector4 ShaderParam = Vector4.Zero; if (Params.MetaData != null) { foreach (H3DMetaDataValue MD in Params.MetaData) { if (MD.Type == H3DMetaDataType.Single) { switch (MD.Name) { case "$ShaderParam0": ShaderParam.W = (float)MD.Values[0]; break; case "$ShaderParam1": ShaderParam.Z = (float)MD.Values[0]; break; case "$ShaderParam2": ShaderParam.Y = (float)MD.Values[0]; break; case "$ShaderParam3": ShaderParam.X = (float)MD.Values[0]; break; } } } } Shdr.SetVtxVector4(85, ShaderParam); //Send values from material matching register ids to names. foreach (KeyValuePair <uint, System.Numerics.Vector4> KV in Params.VtxShaderUniforms) { Shdr.SetVtxVector4((int)KV.Key, KV.Value.ToVector4()); } foreach (KeyValuePair <uint, System.Numerics.Vector4> KV in Params.GeoShaderUniforms) { Shdr.SetGeoVector4((int)KV.Key, KV.Value.ToVector4()); } Vector4 MatAmbient = new Vector4( Params.AmbientColor.R / 255f, Params.AmbientColor.G / 255f, Params.AmbientColor.B / 255F, Params.ColorScale); Vector4 MatDiffuse = new Vector4( Params.DiffuseColor.R / 255f, Params.DiffuseColor.G / 255f, Params.DiffuseColor.B / 255f, 1f); Vector4 TexCoordMap = new Vector4( Params.TextureSources[0], Params.TextureSources[1], Params.TextureSources[2], Params.TextureSources[3]); Shdr.SetVtxVector4(DefaultShaderIds.MatAmbi, MatAmbient); Shdr.SetVtxVector4(DefaultShaderIds.MatDiff, MatDiffuse); Shdr.SetVtxVector4(DefaultShaderIds.TexcMap, TexCoordMap); } UpdateUniforms(); }
private void RenderMeshes(IEnumerable <Mesh> Meshes) { foreach (Mesh Mesh in Meshes) { int n = Mesh.BaseMesh.NodeIndex; if (n < Visibilities.Length && !Visibilities[n]) { continue; } Shader Shader = Shaders[Mesh.BaseMesh.MaterialIndex]; GL.UseProgram(Shader.Handle); Shader.SetVtx4x4Array(DefaultShaderIds.ProjMtx, Renderer.Camera.ProjectionMatrix); Shader.SetVtx3x4Array(DefaultShaderIds.ViewMtx, Renderer.Camera.ViewMatrix * Transform); Shader.SetVtx3x4Array(DefaultShaderIds.NormMtx, Transform.ClearScale()); Shader.SetVtx3x4Array(DefaultShaderIds.WrldMtx, Matrix4.Identity); int MaterialIndex = Mesh.BaseMesh.MaterialIndex; H3DMaterialParams MP = BaseModel.Materials[MaterialIndex].MaterialParams; MaterialState MS = MaterialStates[Mesh.BaseMesh.MaterialIndex]; Vector4 MatAmbient = new Vector4( MS.Ambient.R, MS.Ambient.G, MS.Ambient.B, MP.ColorScale); Vector4 MatDiffuse = new Vector4( MS.Diffuse.R, MS.Diffuse.G, MS.Diffuse.B, MS.Diffuse.A); Shader.SetVtxVector4(DefaultShaderIds.MatAmbi, MatAmbient); Shader.SetVtxVector4(DefaultShaderIds.MatDiff, MatDiffuse); Shader.SetVtx3x4Array(DefaultShaderIds.TexMtx0, MS.Transforms[0]); Shader.SetVtx3x4Array(DefaultShaderIds.TexMtx1, MS.Transforms[1]); Shader.SetVtx2x4Array(DefaultShaderIds.TexMtx2, MS.Transforms[2]); Shader.SetVtxVector4(DefaultShaderIds.TexTran, new Vector4( MS.Transforms[0].Row3.X, MS.Transforms[0].Row3.Y, MS.Transforms[1].Row3.X, MS.Transforms[1].Row3.Y)); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.EmissionUniform), MS.Emission); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.AmbientUniform), MS.Ambient); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.DiffuseUniform), MS.Diffuse); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.Specular0Uniform), MS.Specular0); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.Specular1Uniform), MS.Specular1); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.Constant0Uniform), MS.Constant0); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.Constant1Uniform), MS.Constant1); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.Constant2Uniform), MS.Constant2); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.Constant3Uniform), MS.Constant3); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.Constant4Uniform), MS.Constant4); GL.Uniform4(GL.GetUniformLocation(Shader.Handle, FragmentShaderGenerator.Constant5Uniform), MS.Constant5); Mesh.Texture0Name = MS.Texture0Name; Mesh.Texture1Name = MS.Texture1Name; Mesh.Texture2Name = MS.Texture2Name; Mesh.Render(); } }
private static bool CompareMaterials(H3DMaterialParams LHS, H3DMaterialParams RHS) { bool Equals = true; Equals &= LHS.ShaderReference == RHS.ShaderReference; Equals &= LHS.TranslucencyKind == RHS.TranslucencyKind; Equals &= LHS.TexCoordConfig == RHS.TexCoordConfig; Equals &= LHS.FresnelSelector == RHS.FresnelSelector; Equals &= LHS.BumpMode == RHS.BumpMode; Equals &= LHS.BumpTexture == RHS.BumpTexture; Equals &= LHS.Constant0Assignment == RHS.Constant0Assignment; Equals &= LHS.Constant1Assignment == RHS.Constant1Assignment; Equals &= LHS.Constant2Assignment == RHS.Constant2Assignment; Equals &= LHS.Constant3Assignment == RHS.Constant3Assignment; Equals &= LHS.Constant4Assignment == RHS.Constant4Assignment; Equals &= LHS.Constant5Assignment == RHS.Constant5Assignment; Equals &= LHS.LUTInputAbsolute.Dist0 == RHS.LUTInputAbsolute.Dist0; Equals &= LHS.LUTInputAbsolute.Dist1 == RHS.LUTInputAbsolute.Dist1; Equals &= LHS.LUTInputAbsolute.Fresnel == RHS.LUTInputAbsolute.Fresnel; Equals &= LHS.LUTInputAbsolute.ReflecR == RHS.LUTInputAbsolute.ReflecR; Equals &= LHS.LUTInputAbsolute.ReflecG == RHS.LUTInputAbsolute.ReflecG; Equals &= LHS.LUTInputAbsolute.ReflecB == RHS.LUTInputAbsolute.ReflecB; Equals &= LHS.LUTInputSelection.Dist0 == RHS.LUTInputSelection.Dist0; Equals &= LHS.LUTInputSelection.Dist1 == RHS.LUTInputSelection.Dist1; Equals &= LHS.LUTInputSelection.Fresnel == RHS.LUTInputSelection.Fresnel; Equals &= LHS.LUTInputSelection.ReflecR == RHS.LUTInputSelection.ReflecR; Equals &= LHS.LUTInputSelection.ReflecG == RHS.LUTInputSelection.ReflecG; Equals &= LHS.LUTInputSelection.ReflecB == RHS.LUTInputSelection.ReflecB; Equals &= LHS.LUTInputScale.Dist0 == RHS.LUTInputScale.Dist0; Equals &= LHS.LUTInputScale.Dist1 == RHS.LUTInputScale.Dist1; Equals &= LHS.LUTInputScale.Fresnel == RHS.LUTInputScale.Fresnel; Equals &= LHS.LUTInputScale.ReflecR == RHS.LUTInputScale.ReflecR; Equals &= LHS.LUTInputScale.ReflecG == RHS.LUTInputScale.ReflecG; Equals &= LHS.LUTInputScale.ReflecB == RHS.LUTInputScale.ReflecB; Equals &= LHS.LUTDist0TableName == RHS.LUTDist0TableName; Equals &= LHS.LUTDist1TableName == RHS.LUTDist1TableName; Equals &= LHS.LUTFresnelTableName == RHS.LUTFresnelTableName; Equals &= LHS.LUTReflecRTableName == RHS.LUTReflecRTableName; Equals &= LHS.LUTReflecGTableName == RHS.LUTReflecGTableName; Equals &= LHS.LUTReflecBTableName == RHS.LUTReflecBTableName; Equals &= LHS.LUTDist0SamplerName == RHS.LUTDist0SamplerName; Equals &= LHS.LUTDist1SamplerName == RHS.LUTDist1SamplerName; Equals &= LHS.LUTFresnelSamplerName == RHS.LUTFresnelSamplerName; Equals &= LHS.LUTReflecRSamplerName == RHS.LUTReflecRSamplerName; Equals &= LHS.LUTReflecGSamplerName == RHS.LUTReflecGSamplerName; Equals &= LHS.LUTReflecBSamplerName == RHS.LUTReflecBSamplerName; for (int i = 0; i < 6; i++) { Equals &= LHS.TexEnvStages[i].Source.Color[0] == RHS.TexEnvStages[i].Source.Color[0]; Equals &= LHS.TexEnvStages[i].Source.Color[1] == RHS.TexEnvStages[i].Source.Color[1]; Equals &= LHS.TexEnvStages[i].Source.Color[2] == RHS.TexEnvStages[i].Source.Color[2]; Equals &= LHS.TexEnvStages[i].Source.Alpha[0] == RHS.TexEnvStages[i].Source.Alpha[0]; Equals &= LHS.TexEnvStages[i].Source.Alpha[1] == RHS.TexEnvStages[i].Source.Alpha[1]; Equals &= LHS.TexEnvStages[i].Source.Alpha[2] == RHS.TexEnvStages[i].Source.Alpha[2]; Equals &= LHS.TexEnvStages[i].Operand.Color[0] == RHS.TexEnvStages[i].Operand.Color[0]; Equals &= LHS.TexEnvStages[i].Operand.Color[1] == RHS.TexEnvStages[i].Operand.Color[1]; Equals &= LHS.TexEnvStages[i].Operand.Color[2] == RHS.TexEnvStages[i].Operand.Color[2]; Equals &= LHS.TexEnvStages[i].Operand.Alpha[0] == RHS.TexEnvStages[i].Operand.Alpha[0]; Equals &= LHS.TexEnvStages[i].Operand.Alpha[1] == RHS.TexEnvStages[i].Operand.Alpha[1]; Equals &= LHS.TexEnvStages[i].Operand.Alpha[2] == RHS.TexEnvStages[i].Operand.Alpha[2]; Equals &= LHS.TexEnvStages[i].Combiner.Color == RHS.TexEnvStages[i].Combiner.Color; Equals &= LHS.TexEnvStages[i].Combiner.Alpha == RHS.TexEnvStages[i].Combiner.Alpha; Equals &= LHS.TexEnvStages[i].Scale.Color == RHS.TexEnvStages[i].Scale.Color; Equals &= LHS.TexEnvStages[i].Scale.Alpha == RHS.TexEnvStages[i].Scale.Alpha; Equals &= LHS.TexEnvStages[i].UpdateColorBuffer == RHS.TexEnvStages[i].UpdateColorBuffer; Equals &= LHS.TexEnvStages[i].UpdateAlphaBuffer == RHS.TexEnvStages[i].UpdateAlphaBuffer; } Equals &= LHS.TexEnvBufferColor.R == RHS.TexEnvBufferColor.R; Equals &= LHS.TexEnvBufferColor.G == RHS.TexEnvBufferColor.G; Equals &= LHS.TexEnvBufferColor.B == RHS.TexEnvBufferColor.B; Equals &= LHS.TexEnvBufferColor.A == RHS.TexEnvBufferColor.A; return(Equals); }
private static int GetMaterialShaderHash(H3DMaterialParams Params) { FNV1a HashGen = new FNV1a(); HashGen.Hash(Params.ShaderReference?.GetHashCode() ?? 0); HashGen.Hash(Params.TranslucencyKind.GetHashCode()); HashGen.Hash(Params.TexCoordConfig.GetHashCode()); HashGen.Hash(Params.FresnelSelector.GetHashCode()); HashGen.Hash(Params.BumpMode.GetHashCode()); HashGen.Hash(Params.BumpTexture.GetHashCode()); HashGen.Hash(Params.Constant0Assignment.GetHashCode()); HashGen.Hash(Params.Constant1Assignment.GetHashCode()); HashGen.Hash(Params.Constant2Assignment.GetHashCode()); HashGen.Hash(Params.Constant3Assignment.GetHashCode()); HashGen.Hash(Params.Constant4Assignment.GetHashCode()); HashGen.Hash(Params.Constant5Assignment.GetHashCode()); HashGen.Hash(Params.LUTInputAbsolute.Dist0.GetHashCode()); HashGen.Hash(Params.LUTInputAbsolute.Dist1.GetHashCode()); HashGen.Hash(Params.LUTInputAbsolute.Fresnel.GetHashCode()); HashGen.Hash(Params.LUTInputAbsolute.ReflecR.GetHashCode()); HashGen.Hash(Params.LUTInputAbsolute.ReflecG.GetHashCode()); HashGen.Hash(Params.LUTInputAbsolute.ReflecB.GetHashCode()); HashGen.Hash(Params.LUTInputSelection.Dist0.GetHashCode()); HashGen.Hash(Params.LUTInputSelection.Dist1.GetHashCode()); HashGen.Hash(Params.LUTInputSelection.Fresnel.GetHashCode()); HashGen.Hash(Params.LUTInputSelection.ReflecR.GetHashCode()); HashGen.Hash(Params.LUTInputSelection.ReflecG.GetHashCode()); HashGen.Hash(Params.LUTInputSelection.ReflecB.GetHashCode()); HashGen.Hash(Params.LUTInputScale.Dist0.GetHashCode()); HashGen.Hash(Params.LUTInputScale.Dist1.GetHashCode()); HashGen.Hash(Params.LUTInputScale.Fresnel.GetHashCode()); HashGen.Hash(Params.LUTInputScale.ReflecR.GetHashCode()); HashGen.Hash(Params.LUTInputScale.ReflecG.GetHashCode()); HashGen.Hash(Params.LUTInputScale.ReflecB.GetHashCode()); HashGen.Hash(Params.LUTDist0TableName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTDist1TableName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTFresnelTableName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTReflecRTableName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTReflecGTableName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTReflecBTableName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTDist0SamplerName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTDist1SamplerName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTFresnelSamplerName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTReflecRSamplerName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTReflecGSamplerName?.GetHashCode() ?? 0); HashGen.Hash(Params.LUTReflecBSamplerName?.GetHashCode() ?? 0); foreach (PICATexEnvStage Stage in Params.TexEnvStages) { HashGen.Hash(Stage.Source.Color[0].GetHashCode()); HashGen.Hash(Stage.Source.Color[1].GetHashCode()); HashGen.Hash(Stage.Source.Color[2].GetHashCode()); HashGen.Hash(Stage.Source.Alpha[0].GetHashCode()); HashGen.Hash(Stage.Source.Alpha[1].GetHashCode()); HashGen.Hash(Stage.Source.Alpha[2].GetHashCode()); HashGen.Hash(Stage.Operand.Color[0].GetHashCode()); HashGen.Hash(Stage.Operand.Color[1].GetHashCode()); HashGen.Hash(Stage.Operand.Color[2].GetHashCode()); HashGen.Hash(Stage.Operand.Alpha[0].GetHashCode()); HashGen.Hash(Stage.Operand.Alpha[1].GetHashCode()); HashGen.Hash(Stage.Operand.Alpha[2].GetHashCode()); HashGen.Hash(Stage.Combiner.Color.GetHashCode()); HashGen.Hash(Stage.Combiner.Alpha.GetHashCode()); HashGen.Hash(Stage.Scale.Color.GetHashCode()); HashGen.Hash(Stage.Scale.Alpha.GetHashCode()); HashGen.Hash(Stage.UpdateColorBuffer.GetHashCode()); HashGen.Hash(Stage.UpdateAlphaBuffer.GetHashCode()); } HashGen.Hash(Params.TexEnvBufferColor.R.GetHashCode()); HashGen.Hash(Params.TexEnvBufferColor.G.GetHashCode()); HashGen.Hash(Params.TexEnvBufferColor.B.GetHashCode()); HashGen.Hash(Params.TexEnvBufferColor.A.GetHashCode()); return((int)HashGen.HashCode); }
public H3DModel ToH3DModel() { H3DModel Output = new H3DModel() { Name = Name }; //Skeleton foreach (GFBone Bone in Skeleton) { Output.Skeleton.Add(new H3DBone() { ParentIndex = (short)Skeleton.FindIndex(x => x.Name == Bone.Parent), Name = Bone.Name, Scale = Bone.Scale, Rotation = Bone.Rotation, Translation = Bone.Translation }); } foreach (H3DBone Bone in Output.Skeleton) { Bone.CalculateTransform(Output.Skeleton); Bone.Flags |= H3DBoneFlags.IsSegmentScaleCompensate; } if (Output.Skeleton.Count > 0) { Output.Flags = H3DModelFlags.HasSkeleton; } //Materials foreach (GFMaterial Material in Materials) { H3DMaterial Mat = new H3DMaterial(); H3DMaterialParams Params = Mat.MaterialParams; Mat.Name = Material.MaterialName; Params.FragmentFlags = H3DFragmentFlags.IsLUTReflectionEnabled; Array.Copy(Material.TextureSources, Params.TextureSources, 4); for (int Unit = 0; Unit < Material.TextureCoords.Length; Unit++) { string TextureName = Material.TextureCoords[Unit].Name; Mat.EnabledTextures[Unit] = TextureName != null; switch (Unit) { case 0: Mat.Texture0Name = TextureName; break; case 1: Mat.Texture1Name = TextureName; break; case 2: Mat.Texture2Name = TextureName; break; } //Texture Coords GFTextureMappingType MappingType = Material.TextureCoords[Unit].MappingType; Params.TextureCoords[Unit].MappingType = (H3DTextureMappingType)MappingType; Params.TextureCoords[Unit].Scale = Material.TextureCoords[Unit].Scale; Params.TextureCoords[Unit].Rotation = Material.TextureCoords[Unit].Rotation; Params.TextureCoords[Unit].Translation = Material.TextureCoords[Unit].Translation; //Texture Mapper Mat.TextureMappers[Unit].WrapU = (PICATextureWrap)Material.TextureCoords[Unit].WrapU; Mat.TextureMappers[Unit].WrapV = (PICATextureWrap)Material.TextureCoords[Unit].WrapV; Mat.TextureMappers[Unit].MagFilter = (H3DTextureMagFilter)Material.TextureCoords[Unit].MagFilter; Mat.TextureMappers[Unit].MinFilter = (H3DTextureMinFilter)Material.TextureCoords[Unit].MinFilter; Mat.TextureMappers[Unit].MinLOD = (byte)Material.TextureCoords[Unit].MinLOD; Mat.TextureMappers[Unit].BorderColor = Material.BorderColor[Unit]; } Params.EmissionColor = Material.EmissionColor; Params.AmbientColor = Material.AmbientColor; Params.DiffuseColor = Material.DiffuseColor; Params.Specular0Color = Material.Specular0Color; Params.Specular1Color = Material.Specular1Color; Params.Constant0Color = Material.Constant0Color; Params.Constant1Color = Material.Constant1Color; Params.Constant2Color = Material.Constant2Color; Params.Constant3Color = Material.Constant3Color; Params.Constant4Color = Material.Constant4Color; Params.Constant5Color = Material.Constant5Color; Params.BlendColor = Material.BlendColor; //HACK: It's usually 0 on Sun/Moon, this causes issues on some //models being rendered transparent (Shader differences). Params.DiffuseColor.A = 0xff; Params.ColorScale = 1f; Params.LUTInputAbsolute = Material.LUTInputAbsolute; Params.LUTInputSelection = Material.LUTInputSelection; Params.LUTInputScale = Material.LUTInputScale; Params.ColorOperation = Material.ColorOperation; Params.BlendFunction = Material.BlendFunction; Params.LogicalOperation = Material.LogicalOperation; Params.AlphaTest = Material.AlphaTest; Params.StencilTest = Material.StencilTest; Params.StencilOperation = Material.StencilOperation; Params.DepthColorMask = Material.DepthColorMask; Params.FaceCulling = Material.FaceCulling; Params.ColorBufferRead = Material.ColorBufferRead; Params.ColorBufferWrite = Material.ColorBufferWrite; Params.StencilBufferRead = Material.StencilBufferRead; Params.StencilBufferWrite = Material.StencilBufferWrite; Params.DepthBufferRead = Material.DepthBufferRead; Params.DepthBufferWrite = Material.DepthBufferWrite; if (Material.LUT0HashId != 0) { Params.LUTReflecRTableName = DefaultLUTName; Params.LUTReflecRSamplerName = GetLUTName(Material.LUT0HashId); } if (Material.LUT1HashId != 0) { Params.LUTReflecGTableName = DefaultLUTName; Params.LUTReflecGSamplerName = GetLUTName(Material.LUT1HashId); } if (Material.LUT2HashId != 0) { Params.LUTReflecBTableName = DefaultLUTName; Params.LUTReflecBSamplerName = GetLUTName(Material.LUT2HashId); } if (Material.BumpTexture != -1) { Params.BumpTexture = (byte)Material.BumpTexture; Params.BumpMode = H3DBumpMode.AsBump; } Params.Constant0Assignment = Material.Constant0Assignment; Params.Constant1Assignment = Material.Constant1Assignment; Params.Constant2Assignment = Material.Constant2Assignment; Params.Constant3Assignment = Material.Constant3Assignment; Params.Constant4Assignment = Material.Constant4Assignment; Params.Constant5Assignment = Material.Constant5Assignment; string VtxShaderName = Material.VtxShaderName; //Make shader names match X/Y/OR/AS shader names. if (VtxShaderName == "Poke" || VtxShaderName == "PokeNormal") { VtxShaderName = "PokePack"; } Params.ShaderReference = $"0@{VtxShaderName}"; Params.ModelReference = $"{Mat.Name}@{Name}"; /* * Add those for compatibility with the older BCH models. * It's worth noting that ShaderParam0 is usually used as "UVScale" on model that uses * geometry shader to make billboarded point sprites. On the new shader it have a * multiplication of the Color by 3, while the older one doesn't have such multiplication, * so for compatibility with the older shader, the easiest thing to do is just multiply the * scale by 3 to give the same results on the old shader. */ Params.MetaData = new H3DMetaData(); Params.MetaData.Add(new H3DMetaDataValue("EdgeType", Material.EdgeType)); Params.MetaData.Add(new H3DMetaDataValue("IDEdgeEnable", Material.IDEdgeEnable)); Params.MetaData.Add(new H3DMetaDataValue("EdgeID", Material.EdgeID)); Params.MetaData.Add(new H3DMetaDataValue("ProjectionType", Material.ProjectionType)); Params.MetaData.Add(new H3DMetaDataValue("RimPow", Material.RimPower)); Params.MetaData.Add(new H3DMetaDataValue("RimScale", Material.RimScale)); Params.MetaData.Add(new H3DMetaDataValue("PhongPow", Material.PhongPower)); Params.MetaData.Add(new H3DMetaDataValue("PhongScale", Material.PhongScale)); Params.MetaData.Add(new H3DMetaDataValue("IDEdgeOffsetEnable", Material.IDEdgeOffsetEnable)); Params.MetaData.Add(new H3DMetaDataValue("EdgeMapAlphaMask", Material.EdgeMapAlphaMask)); Params.MetaData.Add(new H3DMetaDataValue("BakeTexture0", Material.BakeTexture0)); Params.MetaData.Add(new H3DMetaDataValue("BakeTexture1", Material.BakeTexture1)); Params.MetaData.Add(new H3DMetaDataValue("BakeTexture2", Material.BakeTexture2)); Params.MetaData.Add(new H3DMetaDataValue("BakeConstant0", Material.BakeConstant0)); Params.MetaData.Add(new H3DMetaDataValue("BakeConstant1", Material.BakeConstant1)); Params.MetaData.Add(new H3DMetaDataValue("BakeConstant2", Material.BakeConstant2)); Params.MetaData.Add(new H3DMetaDataValue("BakeConstant3", Material.BakeConstant3)); Params.MetaData.Add(new H3DMetaDataValue("BakeConstant4", Material.BakeConstant4)); Params.MetaData.Add(new H3DMetaDataValue("BakeConstant5", Material.BakeConstant5)); Params.MetaData.Add(new H3DMetaDataValue("VertexShaderType", Material.VertexShaderType)); Params.MetaData.Add(new H3DMetaDataValue("ShaderParam0", Material.ShaderParam0 * 3)); Params.MetaData.Add(new H3DMetaDataValue("ShaderParam1", Material.ShaderParam1)); Params.MetaData.Add(new H3DMetaDataValue("ShaderParam2", Material.ShaderParam2)); Params.MetaData.Add(new H3DMetaDataValue("ShaderParam3", Material.ShaderParam3)); Output.Materials.Add(Mat); } //Meshes Output.MeshNodesTree = new H3DPatriciaTree(); foreach (GFMesh Mesh in Meshes) { //Note: GFModel have one Vertex Buffer for each SubMesh, //while on H3D all SubMeshes shares the same Vertex Buffer. //For this reason we need to store SubMeshes as Meshes on H3D. foreach (GFSubMesh SubMesh in Mesh.SubMeshes) { int NodeIndex = Output.MeshNodesTree.Find(Mesh.Name); if (NodeIndex == -1) { Output.MeshNodesTree.Add(Mesh.Name); Output.MeshNodesVisibility.Add(true); NodeIndex = Output.MeshNodesCount++; } List <H3DSubMesh> SubMeshes = new List <H3DSubMesh>(); ushort[] BoneIndices = new ushort[SubMesh.BoneIndicesCount]; for (int Index = 0; Index < BoneIndices.Length; Index++) { BoneIndices[Index] = SubMesh.BoneIndices[Index]; } H3DSubMeshSkinning SMSk = Output.Skeleton.Count > 0 ? H3DSubMeshSkinning.Smooth : H3DSubMeshSkinning.None; SubMeshes.Add(new H3DSubMesh() { Skinning = SMSk, BoneIndicesCount = SubMesh.BoneIndicesCount, BoneIndices = BoneIndices, Indices = SubMesh.Indices }); H3DMesh M = new H3DMesh( SubMesh.RawBuffer, SubMesh.VertexStride, SubMesh.Attributes, SubMesh.FixedAttributes, SubMeshes); M.Skinning = H3DMeshSkinning.Smooth; int MatIndex = Materials.FindIndex(x => x.MaterialName == SubMesh.Name); GFMaterial Mat = Materials[MatIndex]; M.MaterialIndex = (ushort)MatIndex; M.NodeIndex = (ushort)NodeIndex; M.Layer = Mat.RenderLayer; M.Priority = Mat.RenderPriority; M.UpdateBoolUniforms(Output.Materials[MatIndex]); Output.AddMesh(M); } } return(Output); }
public GLSLFragmentShaderGenerator(H3DMaterialParams @params) => Params = @params;
public H3D ToH3D() { H3D Output = new H3D(); H3DLUT L = new H3DLUT(); L.Name = GFModel.DefaultLUTName; for (int MdlIndex = 0; MdlIndex < Models.Count; MdlIndex++) { GFModel Model = Models[MdlIndex]; H3DModel Mdl = Model.ToH3DModel(); for (int MatIndex = 0; MatIndex < Model.Materials.Count; MatIndex++) { H3DMaterialParams Params = Mdl.Materials[MatIndex].MaterialParams; string FragShaderName = Model.Materials[MatIndex].FragShaderName; string VtxShaderName = Model.Materials[MatIndex].VtxShaderName; GFShader FragShader = Shaders.FirstOrDefault(x => x.Name == FragShaderName); GFShader VtxShader = Shaders.FirstOrDefault(x => x.Name == VtxShaderName); if (FragShader != null) { Params.TexEnvBufferColor = FragShader.TexEnvBufferColor; Array.Copy(FragShader.TexEnvStages, Params.TexEnvStages, 6); } if (VtxShader != null) { foreach (KeyValuePair <uint, Vector4> KV in VtxShader.VtxShaderUniforms) { Params.VtxShaderUniforms.Add(KV.Key, KV.Value); } foreach (KeyValuePair <uint, Vector4> KV in VtxShader.GeoShaderUniforms) { Params.GeoShaderUniforms.Add(KV.Key, KV.Value); } } } foreach (GFLUT LUT in Model.LUTs) { L.Samplers.Add(new H3DLUTSampler() { Name = LUT.Name, Table = LUT.Table }); } Output.Models.Add(Mdl); } Output.LUTs.Add(L); Output.CopyMaterials(); foreach (GFTexture Texture in Textures) { Output.Textures.Add(Texture.ToH3DTexture()); } return(Output); }
public void Render() { Shader Shader = Parent.Shaders[BaseMesh.MaterialIndex]; H3DMaterialParams Params = Material.MaterialParams; Params.BlendFunction.SetGL(); Params.StencilTest.SetGL(); Params.StencilOperation.SetGL(); Params.DepthColorMask.SetGL(); Params.AlphaTest.SetGL(); GL.BlendColor(Params.BlendColor.ToColor4()); GL.CullFace(Params.FaceCulling.ToCullFaceMode()); GL.PolygonOffset(0, Params.PolygonOffsetUnit); SetState(EnableCap.Blend, Params.ColorOperation.BlendMode == PICABlendMode.Blend); SetState(EnableCap.StencilTest, Params.StencilTest.Enabled); SetState(EnableCap.DepthTest, Params.DepthColorMask.Enabled); SetState(EnableCap.CullFace, Params.FaceCulling != PICAFaceCulling.Never); Parent.Renderer.TryBindLUT(4, Params.LUTDist0TableName, Params.LUTDist0SamplerName); Parent.Renderer.TryBindLUT(5, Params.LUTDist1TableName, Params.LUTDist1SamplerName); Parent.Renderer.TryBindLUT(6, Params.LUTFresnelTableName, Params.LUTFresnelSamplerName); Parent.Renderer.TryBindLUT(7, Params.LUTReflecRTableName, Params.LUTReflecRSamplerName); Parent.Renderer.TryBindLUT(8, Params.LUTReflecGTableName ?? Params.LUTReflecRTableName, Params.LUTReflecGSamplerName ?? Params.LUTReflecRSamplerName); Parent.Renderer.TryBindLUT(9, Params.LUTReflecBTableName ?? Params.LUTReflecRTableName, Params.LUTReflecBSamplerName ?? Params.LUTReflecRSamplerName); //Setup texture units if (Texture0Name != null) { //Only the texture unit 0 can have a Cube Map texture if (Params.TextureCoords[0].MappingType == H3DTextureMappingType.CameraCubeEnvMap) { Parent.Renderer.TryBindTexture(3, Texture0Name); SetWrapAndFilter(TextureTarget.TextureCubeMap, 0); } else { Parent.Renderer.TryBindTexture(0, Texture0Name); SetWrapAndFilter(TextureTarget.Texture2D, 0); } } if (Texture1Name != null) { Parent.Renderer.TryBindTexture(1, Texture1Name); SetWrapAndFilter(TextureTarget.Texture2D, 1); } if (Texture2Name != null) { Parent.Renderer.TryBindTexture(2, Texture2Name); SetWrapAndFilter(TextureTarget.Texture2D, 2); } Shader.SetVtxVector4(DefaultShaderIds.PosOffs, PosOffs); Shader.SetVtxVector4(DefaultShaderIds.IrScale + 0, Scales0); Shader.SetVtxVector4(DefaultShaderIds.IrScale + 1, Scales1); //Render all SubMeshes GL.BindVertexArray(VAOHandle); foreach (H3DSubMesh SM in BaseMesh.SubMeshes) { bool SmoothSkin = SM.Skinning == H3DSubMeshSkinning.Smooth; Matrix4[] Transforms = new Matrix4[20]; for (int Index = 0; Index < Transforms.Length; Index++) { Matrix4 Transform = Matrix4.Identity; if (Index < SM.BoneIndicesCount && SM.BoneIndices[Index] < Parent.SkeletonTransforms.Length) { int BoneIndex = SM.BoneIndices[Index]; Transform = Parent.SkeletonTransforms[BoneIndex]; if (SmoothSkin) { Transform = Parent.InverseTransforms[BoneIndex] * Transform; } //Build billboard matrix if needed (used to make the bones follow the camera view) H3DBone Bone = Parent.BaseModel.Skeleton[BoneIndex]; if (Bone.BillboardMode != H3DBillboardMode.Off) { Matrix4 BillMtx = Matrix4.Identity; Matrix4 WrldMtx = Parent.Transform * Parent.Renderer.Camera.ViewMatrix; Matrix4 BoneMtx = Matrix4.CreateRotationX(Bone.Rotation.X) * Matrix4.CreateRotationY(Bone.Rotation.Y) * Matrix4.CreateRotationZ(Bone.Rotation.Z); Vector3 X, Y, Z; X = Y = Z = Vector3.Zero; switch (Bone.BillboardMode) { case H3DBillboardMode.World: Y = Vector3.Normalize(WrldMtx.Row1.Xyz); Z = Vector3.UnitZ; break; case H3DBillboardMode.WorldViewpoint: Y = Vector3.Normalize(WrldMtx.Row1.Xyz); Z = Vector3.Normalize(-WrldMtx.Row3.Xyz); break; case H3DBillboardMode.Screen: Y = Vector3.Normalize(BoneMtx.Row1.Xyz); Z = Vector3.UnitZ; break; case H3DBillboardMode.ScreenViewpoint: Y = Vector3.Normalize(BoneMtx.Row1.Xyz); Z = Vector3.Normalize(-WrldMtx.Row3.Xyz); break; case H3DBillboardMode.YAxial: Y = Vector3.Normalize(WrldMtx.Row1.Xyz); Z = Vector3.UnitZ; break; case H3DBillboardMode.YAxialViewpoint: Y = Vector3.Normalize(WrldMtx.Row1.Xyz); Z = Vector3.Normalize(-WrldMtx.Row3.Xyz); break; } X = Vector3.Normalize(Vector3.Cross(Y, Z)); Y = Vector3.Normalize(Vector3.Cross(Z, X)); BillMtx.Row0 = new Vector4(X.X, Y.X, Z.X, 0); BillMtx.Row1 = new Vector4(X.Y, Y.Y, Z.Y, 0); BillMtx.Row2 = new Vector4(X.Z, Y.Z, Z.Z, 0); BillMtx.Row3 = (Transform * WrldMtx).Row3; WrldMtx = WrldMtx.ClearScale(); WrldMtx.Invert(); Transform = Matrix4.CreateScale(Transform.ExtractScale()) * BillMtx * WrldMtx; } } Shader.SetVtx3x4Array(DefaultShaderIds.UnivReg + Index * 3, Transform); } int BoolsLocation = GL.GetUniformLocation(Shader.Handle, ShaderGenerator.BoolsName); GL.Uniform1(BoolsLocation, SM.BoolUniforms); GL.DrawElements(PrimitiveType.Triangles, SM.Indices.Length, DrawElementsType.UnsignedShort, SM.Indices); } GL.BindVertexArray(0); GL.BindTexture(TextureTarget.Texture2D, 0); GL.BindTexture(TextureTarget.TextureCubeMap, 0); }
public H3D ToH3D() { H3D Output = new H3D(); Output.SourceData.Add(this); H3DLUT L = new H3DLUT(); L.Name = GFModel.DefaultLUTName; for (int MdlIndex = 0; MdlIndex < Models.Count; MdlIndex++) { GFModel Model = Models[MdlIndex]; H3DModel Mdl = Model.ToH3DModel(); for (int MatIndex = 0; MatIndex < Model.Materials.Count; MatIndex++) { H3DMaterialParams Params = Mdl.Materials[MatIndex].MaterialParams; string FragShaderName = Model.Materials[MatIndex].FragShaderName; string VtxShaderName = Model.Materials[MatIndex].VtxShaderName; GFShader FragShader = MaterialShaders.FirstOrDefault(x => x.Name == FragShaderName); GFShader VtxShader = MaterialShaders.FirstOrDefault(x => x.Name == VtxShaderName); if (FragShader != null) { Params.TexEnvBufferColor = FragShader.TexEnvBufferColor; Array.Copy(FragShader.TexEnvStages, Params.TexEnvStages, 6); } Params.MetaData.Add(new H3DMetaDataValue("OriginMaterialHash", (int)GetTexEnvConfigHash(Params))); if (VtxShader != null) { foreach (KeyValuePair <uint, Vector4> KV in VtxShader.VtxShaderUniforms) { Params.VtxShaderUniforms.Add(KV.Key, KV.Value); } foreach (KeyValuePair <uint, Vector4> KV in VtxShader.GeoShaderUniforms) { Params.GeoShaderUniforms.Add(KV.Key, KV.Value); } } } int Index = 1; while (Output.Models.Contains(Mdl.Name)) { Mdl.Name = $"{Mdl.Name}_{Index}"; } Model.AddToH3DLUT(L); Output.Models.Add(Mdl); } Output.LUTs.Add(L); Output.CopyMaterials(); foreach (GFTexture Texture in Textures) { Output.Textures.Add(Texture.ToH3DTexture()); } /*Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(Output, Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonSerializerSettings() * { * ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore * }));*/ return(Output); }
public MaterialState[] GetMaterialStates() { if (State == AnimationState.Stopped) { ResetStates(); } if (State != AnimationState.Playing || Elements.Count == 0) { return(States); } for (int i = 0; i < Elements.Count; i++) { int Index = Indices[i]; MaterialState State = States[Index]; H3DMaterial Material = Materials[Index]; H3DMaterialParams Params = Material.MaterialParams; H3DAnimationElement Elem = Elements[i]; H3DTextureCoord[] TC = new H3DTextureCoord[] { Params.TextureCoords[0], Params.TextureCoords[1], Params.TextureCoords[2] }; if (Elem.PrimitiveType == H3DPrimitiveType.RGBA) { H3DAnimRGBA RGBA = (H3DAnimRGBA)Elem.Content; switch (Elem.TargetType) { case H3DTargetType.MaterialEmission: SetRGBA(RGBA, ref State.Emission); break; case H3DTargetType.MaterialAmbient: SetRGBA(RGBA, ref State.Ambient); break; case H3DTargetType.MaterialDiffuse: SetRGBA(RGBA, ref State.Diffuse); break; case H3DTargetType.MaterialSpecular0: SetRGBA(RGBA, ref State.Specular0); break; case H3DTargetType.MaterialSpecular1: SetRGBA(RGBA, ref State.Specular1); break; case H3DTargetType.MaterialConstant0: SetRGBA(RGBA, ref State.Constant0); break; case H3DTargetType.MaterialConstant1: SetRGBA(RGBA, ref State.Constant1); break; case H3DTargetType.MaterialConstant2: SetRGBA(RGBA, ref State.Constant2); break; case H3DTargetType.MaterialConstant3: SetRGBA(RGBA, ref State.Constant3); break; case H3DTargetType.MaterialConstant4: SetRGBA(RGBA, ref State.Constant4); break; case H3DTargetType.MaterialConstant5: SetRGBA(RGBA, ref State.Constant5); break; } } else if (Elem.PrimitiveType == H3DPrimitiveType.Vector2D) { H3DAnimVector2D Vector = (H3DAnimVector2D)Elem.Content; switch (Elem.TargetType) { case H3DTargetType.MaterialTexCoord0Scale: SetVector2(Vector, ref TC[0].Scale); break; case H3DTargetType.MaterialTexCoord1Scale: SetVector2(Vector, ref TC[1].Scale); break; case H3DTargetType.MaterialTexCoord2Scale: SetVector2(Vector, ref TC[2].Scale); break; case H3DTargetType.MaterialTexCoord0Trans: SetVector2(Vector, ref TC[0].Translation); break; case H3DTargetType.MaterialTexCoord1Trans: SetVector2(Vector, ref TC[1].Translation); break; case H3DTargetType.MaterialTexCoord2Trans: SetVector2(Vector, ref TC[2].Translation); break; } } else if (Elem.PrimitiveType == H3DPrimitiveType.Float) { H3DFloatKeyFrameGroup Float = ((H3DAnimFloat)Elem.Content).Value; if (!Float.Exists) { continue; } float Value = Float.GetFrameValue(Frame); switch (Elem.TargetType) { case H3DTargetType.MaterialTexCoord0Rot: TC[0].Rotation = Value; break; case H3DTargetType.MaterialTexCoord1Rot: TC[1].Rotation = Value; break; case H3DTargetType.MaterialTexCoord2Rot: TC[2].Rotation = Value; break; } } else if (Elem.PrimitiveType == H3DPrimitiveType.Texture) { H3DFloatKeyFrameGroup Int = ((H3DAnimFloat)Elem.Content).Value; if (!Int.Exists) { continue; } int Value = (int)Int.GetFrameValue(Frame); string Name = TextureNames[Value]; switch (Elem.TargetType) { case H3DTargetType.MaterialMapper0Texture: State.Texture0Name = Name; break; case H3DTargetType.MaterialMapper1Texture: State.Texture1Name = Name; break; case H3DTargetType.MaterialMapper2Texture: State.Texture2Name = Name; break; } } State.Transforms[0] = TC[0].GetTransform().ToMatrix4(); State.Transforms[1] = TC[1].GetTransform().ToMatrix4(); State.Transforms[2] = TC[2].GetTransform().ToMatrix4(); } return(States); }
public HLSLShaderGenerator(H3DMaterialParams @params) => Params = @params;