public override void Draw(DrawContext dc) { if (Model == null) { return; } LitShader litShader = UseAlphaThreshold ? m_shaderAlpha : m_shader; litShader.Texture = TextureOverride; litShader.SamplerState = SamplerState.PointClamp; litShader.MaterialColor = new Vector4(Color * base.GlobalColorTransform); litShader.AmbientLightColor = new Vector3(0.66f, 0.66f, 0.66f); litShader.DiffuseLightColor1 = new Vector3(1f, 1f, 1f); litShader.LightDirection1 = Vector3.Normalize(new Vector3(1f, 1f, 1f)); if (UseAlphaThreshold) { litShader.AlphaThreshold = 0f; } litShader.Transforms.View = Matrix.CreateLookAt(ViewPosition, ViewTarget, Vector3.UnitY); Viewport viewport = Display.Viewport; float num = base.ActualSize.X / base.ActualSize.Y; if (IsPerspective) { litShader.Transforms.Projection = Matrix.CreatePerspectiveFieldOfView(ViewFov, num, 0.1f, 100f) * MatrixUtils.CreateScaleTranslation(0.5f * base.ActualSize.X, -0.5f * base.ActualSize.Y, base.ActualSize.X / 2f, base.ActualSize.Y / 2f) * base.GlobalTransform * MatrixUtils.CreateScaleTranslation(2f / (float)viewport.Width, -2f / (float)viewport.Height, -1f, 1f); } else { Vector3 orthographicFrustumSize = OrthographicFrustumSize; if (orthographicFrustumSize.X < 0f) { orthographicFrustumSize.X = orthographicFrustumSize.Y / num; } else if (orthographicFrustumSize.Y < 0f) { orthographicFrustumSize.Y = orthographicFrustumSize.X * num; } litShader.Transforms.Projection = Matrix.CreateOrthographic(orthographicFrustumSize.X, orthographicFrustumSize.Y, 0f, OrthographicFrustumSize.Z) * MatrixUtils.CreateScaleTranslation(0.5f * base.ActualSize.X, -0.5f * base.ActualSize.Y, base.ActualSize.X / 2f, base.ActualSize.Y / 2f) * base.GlobalTransform * MatrixUtils.CreateScaleTranslation(2f / (float)viewport.Width, -2f / (float)viewport.Height, -1f, 1f); } Display.DepthStencilState = DepthStencilState.Default; Display.BlendState = BlendState.AlphaBlend; Display.RasterizerState = RasterizerState.CullNoneScissor; ProcessBoneHierarchy(Model.RootBone, Matrix.Identity, m_absoluteBoneTransforms); float num2 = (float)Time.RealTime + (float)(GetHashCode() % 1000) / 100f; Matrix m = (AutoRotationVector.LengthSquared() > 0f) ? Matrix.CreateFromAxisAngle(Vector3.Normalize(AutoRotationVector), AutoRotationVector.Length() * num2) : Matrix.Identity; foreach (ModelMesh mesh in Model.Meshes) { litShader.Transforms.World[0] = m_absoluteBoneTransforms[mesh.ParentBone.Index] * ModelMatrix * m; foreach (ModelMeshPart meshPart in mesh.MeshParts) { if (meshPart.IndicesCount > 0) { Display.DrawIndexed(PrimitiveType.TriangleList, litShader, meshPart.VertexBuffer, meshPart.IndexBuffer, meshPart.StartIndex, meshPart.IndicesCount); } } } }
// this is used to update a material's keywords, applying any shader-associated logic to update dependent properties and keywords // this is also invoked when a material is created, modified, or the material's shader is modified or reassigned internal static void UpdateMaterial(Material material, MaterialUpdateType updateType, ShaderID shaderID = ShaderID.Unknown) { // if unknown, look it up from the material's shader // NOTE: this will only work for asset-based shaders.. if (shaderID == ShaderID.Unknown) { shaderID = GetShaderID(material.shader); } switch (shaderID) { case ShaderID.Lit: LitShader.SetMaterialKeywords(material, LitGUI.SetMaterialKeywords); break; case ShaderID.SimpleLit: SimpleLitShader.SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords); break; case ShaderID.Unlit: UnlitShader.SetMaterialKeywords(material); break; case ShaderID.ParticlesLit: ParticlesLitShader.SetMaterialKeywords(material, LitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords); break; case ShaderID.ParticlesSimpleLit: ParticlesSimpleLitShader.SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords); break; case ShaderID.ParticlesUnlit: ParticlesUnlitShader.SetMaterialKeywords(material, null, ParticleGUI.SetMaterialKeywords); break; case ShaderID.SG_Lit: ShaderGraphLitGUI.UpdateMaterial(material, updateType); break; case ShaderID.SG_Unlit: ShaderGraphUnlitGUI.UpdateMaterial(material, updateType); break; default: break; } }
static void UpgradeV1(Material material, ShaderID shaderID) { if (shaderID.IsShaderGraph()) { return; } var shaderPath = ShaderUtils.GetShaderPath((ShaderPathID)shaderID); var upgradeFlag = MaterialUpgrader.UpgradeFlags.LogMessageWhenNoUpgraderFound; switch (shaderID) { case ShaderID.Unlit: MaterialUpgrader.Upgrade(material, new UnlitUpdaterV1(shaderPath), upgradeFlag); UnlitShader.SetMaterialKeywords(material); break; case ShaderID.SimpleLit: MaterialUpgrader.Upgrade(material, new SimpleLitUpdaterV1(shaderPath), upgradeFlag); SimpleLitShader.SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords); break; case ShaderID.Lit: MaterialUpgrader.Upgrade(material, new LitUpdaterV1(shaderPath), upgradeFlag); LitShader.SetMaterialKeywords(material, LitGUI.SetMaterialKeywords); break; case ShaderID.ParticlesLit: MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); ParticlesLitShader.SetMaterialKeywords(material, LitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords); break; case ShaderID.ParticlesSimpleLit: MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); ParticlesSimpleLitShader.SetMaterialKeywords(material, SimpleLitGUI.SetMaterialKeywords, ParticleGUI.SetMaterialKeywords); break; case ShaderID.ParticlesUnlit: MaterialUpgrader.Upgrade(material, new ParticleUpdaterV1(shaderPath), upgradeFlag); ParticlesUnlitShader.SetMaterialKeywords(material, null, ParticleGUI.SetMaterialKeywords); break; } }
// For uniforms and shaders setup. Does not handle vertex/index buffers private unsafe static void EncodeLit(RendererBGFXInstance *sys, bgfx.Encoder *encoder, ref LitShader litShader, ushort viewId, ref float4x4 tx, ref LitMaterialBGFX mat, ref LightingBGFX lighting, ref float4x4 viewTx, byte flipCulling, ref LightingViewSpaceBGFX viewSpaceLightCache, uint depth) { ulong state = mat.state; if (flipCulling != 0) { state = FlipCulling(state); } bgfx.encoder_set_state(encoder, state, 0); fixed(float4x4 *p = &tx) bgfx.encoder_set_transform(encoder, p, 1); float3x3 minvt = math.transpose(math.inverse(new float3x3(tx.c0.xyz, tx.c1.xyz, tx.c2.xyz))); //float3x3 minvt = new float3x3(tx.c0.xyz, tx.c1.xyz, tx.c2.xyz); bgfx.encoder_set_uniform(encoder, litShader.m_uniformModelInverseTranspose, &minvt, 1); // material uniforms setup fixed(float4 *p = &mat.constAlbedo_Opacity) bgfx.encoder_set_uniform(encoder, litShader.m_uniformAlbedoOpacity, p, 1); fixed(float4 *p = &mat.constMetal_Smoothness_Billboarded) bgfx.encoder_set_uniform(encoder, litShader.m_uniformMetalSmoothnessBillboarded, p, 1); fixed(float4 *p = &mat.constEmissive_normalMapZScale) bgfx.encoder_set_uniform(encoder, litShader.m_uniformEmissiveNormalZScale, p, 1); float4 debugVect = sys->m_outputDebugSelect; bgfx.encoder_set_uniform(encoder, litShader.m_uniformOutputDebugSelect, &debugVect, 1); fixed(float4 *p = &mat.smoothness) bgfx.encoder_set_uniform(encoder, litShader.m_uniformSmoothness, p, 1); // textures bgfx.encoder_set_texture(encoder, 0, litShader.m_samplerAlbedoOpacity, mat.texAlbedoOpacity, UInt32.MaxValue); bgfx.encoder_set_texture(encoder, 1, litShader.m_samplerMetal, mat.texMetal, UInt32.MaxValue); bgfx.encoder_set_texture(encoder, 2, litShader.m_samplerNormal, mat.texNormal, UInt32.MaxValue); bgfx.encoder_set_texture(encoder, 4, litShader.m_samplerEmissive, mat.texEmissive, UInt32.MaxValue); fixed(float4 *p = &mat.mainTextureScaleTranslate) bgfx.encoder_set_uniform(encoder, litShader.m_uniformTexMad, p, 1); // ambient fixed(float4 *p = &lighting.ambient) bgfx.encoder_set_uniform(encoder, litShader.m_uniformAmbient, p, 1); // transform lighting to view space, if needed: this only needs to re-compute if the viewId changed // also the lighting view space is per-thread, hence it is passed in lighting.TransformToViewSpace(ref viewTx, ref viewSpaceLightCache, viewId); // dir or point lights fixed(float *p = viewSpaceLightCache.podl_positionOrDirViewSpace) bgfx.encoder_set_uniform(encoder, litShader.m_simplelightPosOrDir, p, (ushort)lighting.numPointOrDirLights); fixed(float *p = lighting.podl_colorIVR) bgfx.encoder_set_uniform(encoder, litShader.m_simplelightColorIVR, p, (ushort)lighting.numPointOrDirLights); // mapped lights (always have to set those or there are undefined samplers) EncodeMappedLight(encoder, ref lighting.mappedLight0, ref litShader.m_mappedLight0, 0, viewSpaceLightCache.mappedLight0_viewPosOrDir); // sampler 6 EncodeMappedLight(encoder, ref lighting.mappedLight1, ref litShader.m_mappedLight1, 1, viewSpaceLightCache.mappedLight1_viewPosOrDir); // sampler 7 fixed(float4 *p = &lighting.mappedLight01sis) bgfx.encoder_set_uniform(encoder, litShader.m_texShadow01sis, p, 1); // csm fixed(float4 *p = &viewSpaceLightCache.csmLight_viewPosOrDir) bgfx.encoder_set_uniform(encoder, litShader.m_dirCSM, p, 1); fixed(float *p = lighting.csmOffsetScale) bgfx.encoder_set_uniform(encoder, litShader.m_offsetScaleCSM, p, 4); fixed(float4 *p = &lighting.csmLight.color_invrangesqr) bgfx.encoder_set_uniform(encoder, litShader.m_colorCSM, p, 1); fixed(float4x4 *p = &lighting.csmLight.projection) bgfx.encoder_set_uniform(encoder, litShader.m_matrixCSM, p, 1); fixed(float4 *p = &lighting.csmLightsis) bgfx.encoder_set_uniform(encoder, litShader.m_sisCSM, p, 1); bgfx.encoder_set_texture(encoder, 5, litShader.m_samplerShadowCSM, lighting.csmLight.shadowMap, UInt32.MaxValue); float4 numlights = new float4(lighting.numPointOrDirLights, lighting.numMappedLights, lighting.numCsmLights, 0.0f); bgfx.encoder_set_uniform(encoder, litShader.m_numLights, &numlights, 1); // fog fixed(float4 *p = &lighting.fogColor) bgfx.encoder_set_uniform(encoder, litShader.m_uniformFogColor, p, 1); fixed(float4 *p = &lighting.fogParams) bgfx.encoder_set_uniform(encoder, litShader.m_uniformFogParams, p, 1); // submit bgfx.encoder_submit(encoder, viewId, litShader.m_prog, depth, (byte)bgfx.DiscardFlags.All); }