//private bool first = true; /// <summary> /// Ejecuta el shader original de formato propio de Quake 3 convertido a una version similar de HLSL en DirectX. /// Estado experimental. Desabilitado por el momento. /// </summary> private void renderShaderMesh(TgcMesh mesh, QShaderData shader) { // if ((shader.Stages[0].HasBlendFunc) ^ (pass == 1)) // { //tiene es opaco se tiene que renderizar en la primer pasada //tiene alpha blending se tiene que renderizar en la segunda pasada // return; //} Device d3dDevice = GuiController.Instance.D3dDevice; Effect fx = shader.Fx; fx.Technique = "tec0"; fx.SetValue("g_mWorld", Matrix.Identity); fx.SetValue("g_mViewProj", mViewProj); fx.SetValue("g_time", time); TgcTexture originalTexture = null; if (mesh.DiffuseMaps != null) { originalTexture = mesh.DiffuseMaps[0]; } fx.Begin(FX.None); for (int j = 0; j < shader.Stages.Count; j++) { fx.BeginPass(j); if (shader.Stages[j].Textures.Count > 0) { mesh.DiffuseMaps[0] = shader.Stages[j].Textures[0]; } //mesh.render(); d3dDevice.SetTexture(0, mesh.DiffuseMaps[0].D3dTexture); if (mesh.LightMap != null) { d3dDevice.SetTexture(1, mesh.LightMap.D3dTexture); } else { d3dDevice.SetTexture(1, null); } mesh.D3dMesh.DrawSubset(0); fx.EndPass(); } fx.End(); if (mesh.DiffuseMaps != null) { mesh.DiffuseMaps[0] = originalTexture; } }
private static List <string> BuildEffectState(QShaderData shader, QShaderStage qstage) { List <string> StateLines = new List <string>(); StateLines.Add("AlphaBlendEnable = " + qstage.HasBlendFunc.ToString().ToLower() + ";"); StateLines.Add("SrcBlend = " + GLtoDXBlend(qstage.BlendSrc) + ";"); StateLines.Add("DestBlend = " + GLtoDXBlend(qstage.BlendDest) + ";"); //StateLines.Add("ZWriteEnable = " + (!qstage.HasBlendFunc).ToString().ToLower() + ";"); if (!shader.Cull.Equals("")) { if (shader.Cull.ToLower().Equals("disable")) { shader.Cull = "None"; } StateLines.Add("CullMode = " + shader.Cull + ";"); } return(StateLines); }
public static string BuildShaderSource(QShaderData shader) { //devuelve el codigo del Fx ShaderCode shaderCode = new ShaderCode(); shaderCode.AuxFuntions.Add(CreateSquareFunction()); shaderCode.AuxFuntions.Add(CreateTriangleFunction()); shaderCode.VsStruct.Add("float4 Pos : POSITION;"); shaderCode.VsStruct.Add("float3 Normal : NORMAL;"); shaderCode.VsStruct.Add("float4 Color : COLOR;"); shaderCode.VsStruct.Add("float2 Tex0 : TEXCOORD0;"); shaderCode.VsStruct.Add("float2 Tex1 : TEXCOORD1;"); shaderCode.PsStruct.Add("float4 Pos : POSITION;"); shaderCode.PsStruct.Add("float3 Normal : NORMAL;"); shaderCode.PsStruct.Add("float4 Color : COLOR;"); shaderCode.PsStruct.Add("float2 Tex0 : TEXCOORD0;"); shaderCode.PsStruct.Add("float2 Tex1 : TEXCOORD1;"); shaderCode.Globals.Add("float4x4 g_mWorld;// : WORLD;"); shaderCode.Globals.Add("float4x4 g_mViewProj;// : VIEWPROJECTION;"); shaderCode.Globals.Add("float g_time;// : TIME;"); shaderCode.Globals.Add("sampler2D texture0 : register(s0);"); shaderCode.Globals.Add("sampler2D texture1 : register(s1);"); foreach (QShaderStage qstage in shader.Stages) { StageCode stageCode = shaderCode.NewStage(); stageCode.VertexLines = BuildVertexShader(shader, qstage); stageCode.PixelLines = BuildPixelShader(shader, qstage); stageCode.StatesLines = BuildEffectState(shader, qstage); } return(shaderCode.Build()); }
/// <summary> /// Parsear shader /// </summary> private static QShaderData ParseShader(QShaderTokenizer tokenizer) { QShaderData qsd = new QShaderData(); qsd.Name = tokenizer.GetNext(); string token = tokenizer.GetNext(); if (!token.Equals("{")) { return(null); } // Parse a shader while (!tokenizer.EOF) { token = tokenizer.GetNext().ToLower(); if (token.Equals("}")) { break; } switch (token) { case "{": QShaderStage stage = ParseStage(tokenizer); // I really really really don't like doing this, which basically just forces lightmaps to use the 'filter' blendmode // but if I don't a lot of textures end up looking too bright. I'm sure I'm jsut missing something, and this shouldn't // be needed. if (stage.IsLightMap() && (stage.HasBlendFunc)) { stage.BlendSrc = "GL_DST_COLOR"; stage.BlendDest = "GL_ZERO"; } // I'm having a ton of trouble getting lightingSpecular to work properly, // so this little hack gets it looking right till I can figure out the problem if (stage.AlphaGen.Equals("lightingspecular")) { stage.BlendSrc = "GL_ONE"; stage.BlendDest = "GL_ZERO"; stage.HasBlendFunc = false; stage.DepthWrite = true; } if (stage.HasBlendFunc) { qsd.Blend = true; } else { qsd.Opaque = true; } qsd.Stages.Add(stage); break; case "cull": qsd.Cull = tokenizer.GetNext(); break; case "deformvertexes": QShaderDeform deform = new QShaderDeform() { Type = tokenizer.GetNext().ToLower() }; switch (deform.Type) { case "wave": deform.Spread = 1.0f / ParserTools.ToFloat(tokenizer.GetNext()); deform.WaveForm = ParseWaveform(tokenizer); break; case "bulge": deform.BulgeWidth = ParserTools.ToFloat(tokenizer.GetNext()); deform.BulgeHeight = ParserTools.ToFloat(tokenizer.GetNext()); deform.BulgeSpeed = ParserTools.ToFloat(tokenizer.GetNext()); break; default: deform = null; break; } if (deform != null) { qsd.VertexDeforms.Add(deform); } break; case "sort": var sort = tokenizer.GetNext().ToLower(); switch (sort) { case "portal": qsd.Sort = 1; break; case "sky": qsd.Sort = 2; break; case "opaque": qsd.Sort = 3; break; case "banner": qsd.Sort = 6; break; case "underwater": qsd.Sort = 8; break; case "additive": qsd.Sort = 9; break; case "nearest": qsd.Sort = 16; break; default: qsd.Sort = int.Parse(sort); break; } ; break; case "surfaceparm": var param = tokenizer.GetNext().ToLower(); switch (param) { case "sky": qsd.Sky = true; break; default: break; } break; default: break; } } if (qsd.Sort > 0) { qsd.Sort = (qsd.Opaque ? 3 : 9); } return(qsd); }
private static List <string> BuildVertexShader(QShaderData shader, QShaderStage stage) { List <string> VertexLines = new List <string>(); VertexLines.Add("PSInput Out = In;"); VertexLines.Add("float4 defPosition = In.Pos;"); for (int i = 0; i < shader.VertexDeforms.Count; ++i) { QShaderDeform deform = shader.VertexDeforms[i]; switch (deform.Type) { case "wave": { string name = "deform" + i; string offName = "deformOff" + i; VertexLines.Add( "float " + offName + " = (In.Pos.x + In.Pos.y + In.Pos.z) * " + ParserTools.ToString(deform.Spread) + ";"); /*float phase = deform.WaveForm.Phase; * //deform.WaveForm.Phase = phase.toFixed(4) + ' + ' + offName; <-----MIRAR ESTA LINEA * VertexLines.Add(CreateWaveForm(name, deform.WaveForm, "g_time")); * deform.WaveForm.Phase = phase;*/ //Parche temporal solo funciona con la funcion seno VertexLines.Add("float " + name + " = " + ParserTools.ToString(deform.WaveForm.Bas) + " + sin((" + ParserTools.ToString(deform.WaveForm.Phase) + " + " + "g_time" + " * " + ParserTools.ToString(deform.WaveForm.Freq) + " + " + offName + ") * 6.283) * " + ParserTools.ToString(deform.WaveForm.Amp) + ";"); //FIN parche VertexLines.Add("defPosition += float4(In.Normal * " + name + ",0);"); } break; case "bulge": { //float alpha = In.Tex0.x*bulgeWidth + g_time; //float deform = sin(alpha)*bulgeHeight; //defPosition += float4(In.Normal * deform0, 0); string deformi = "deform" + i; string alphai = "alpha" + i; VertexLines.Add("float " + alphai + " = In.Tex0.x*" + deform.BulgeWidth + " + g_time*" + deform.BulgeSpeed + ";"); VertexLines.Add("float " + deformi + " = sin(" + alphai + ")*" + deform.BulgeHeight + ";"); VertexLines.Add("defPosition += float4(In.Normal * " + deformi + ",0);"); } break; default: break; } } VertexLines.Add("float4 worldPosition = mul( defPosition, g_mWorld );"); VertexLines.Add("Out.Color = In.Color;"); if (stage.TcGen.Equals("environment")) { VertexLines.Add("float3 viewer = normalize(-worldPosition.xyz);"); VertexLines.Add("float d = dot(In.Normal, viewer);"); VertexLines.Add("float3 reflected = In.Normal*2.0*d - viewer;"); VertexLines.Add("Out.Tex0 = float2(0.5, 0.5) + reflected.xy * 0.5;"); } else { // Standard texturing VertexLines.Add("Out.Tex0 = In.Tex0;"); } // tcMods for (int i = 0; i < stage.TcMods.Count; ++i) { QTcMod tcMod = stage.TcMods[i]; switch (tcMod.Type) { case "rotate": VertexLines.Add("float r = " + ParserTools.ToString(tcMod.Angle) + " * g_time;"); VertexLines.Add("Out.Tex0 -= float2(0.5, 0.5);"); VertexLines.Add("Out.Tex0 = float2(Out.Tex0.x * cos(r) - Out.Tex0.y * sin(r), Out.Tex0.y * cos(r) + Out.Tex0.x * sin(r));"); VertexLines.Add("Out.Tex0 += float2(0.5, 0.5);"); break; case "scroll": VertexLines.Add( "Out.Tex0 += float2(" + ParserTools.ToString(tcMod.SSpeed) + " * g_time, " + ParserTools.ToString(tcMod.TSpeed) + " * g_time);"); break; case "scale": VertexLines.Add( "Out.Tex0 *= float2(" + ParserTools.ToString(tcMod.ScaleX) + ", " + ParserTools.ToString(tcMod.ScaleY) + ");" ); break; case "stretch": VertexLines.Add(CreateWaveForm("stretchWave", tcMod.WaveForm, "")); VertexLines.Add("stretchWave = 1.0 / stretchWave;"); VertexLines.Add("Out.Tex0 *= stretchWave;"); VertexLines.Add("Out.Tex0 += float2(0.5 - (0.5 * stretchWave), 0.5 - (0.5 * stretchWave));"); break; case "turb": var tName = "turbTime" + i; VertexLines.Add("float " + tName + " = " + ParserTools.ToString(tcMod.Turbulance.Phase) + " + g_time * " + ParserTools.ToString(tcMod.Turbulance.Freq) + ";"); VertexLines.Add("Out.Tex0.x += sin( ( ( In.Pos.x + In.Pos.z )* 1.0/128.0 * 0.125 + " + tName + " ) * 6.283) * " + ParserTools.ToString(tcMod.Turbulance.Amp) + ";"); VertexLines.Add("Out.Tex0.y += sin( ( In.Pos.y * 1.0/128.0 * 0.125 + " + tName + " ) * 6.283) * " + ParserTools.ToString(tcMod.Turbulance.Amp) + ";"); break; default: break; } } switch (stage.AlphaGen) { case "lightingspecular": VertexLines.Add("Out.Tex1 = In.Tex1;"); break; default: break; } VertexLines.Add("Out.Pos = mul(worldPosition, g_mViewProj);"); VertexLines.Add("return Out;"); return(VertexLines); }
private static List <string> BuildPixelShader(QShaderData shader, QShaderStage stage) { List <string> PixelLines = new List <string>(); PixelLines.Add("float4 texColor = tex2D(texture0, In.Tex0);"); switch (stage.RgbGen) { case "vertex": PixelLines.Add("float3 rgb = texColor.rgb * In.Color.rgb;"); break; case "wave": PixelLines.Add(CreateWaveForm("rgbWave", stage.RgbWaveform, "")); PixelLines.Add("float3 rgb = texColor.rgb * rgbWave;"); break; default: PixelLines.Add("float3 rgb = texColor.rgb;"); break; } switch (stage.AlphaGen) { case "wave": PixelLines.Add(CreateWaveForm("alpha", stage.AlphaWaveform, "")); //PixelLines.Add("alpha = sin(g_time);"); break; case "lightingspecular": // For now this is VERY special cased. May not work well with all instances of lightingSpecular PixelLines.Add("float4 light = tex2D(texture1, In.Tex1);"); PixelLines.Add("rgb *= light.rgb;"); PixelLines.Add("rgb += light.rgb * texColor.a * 0.6;"); // This was giving me problems, so I'm ignorning an actual specular calculation for now PixelLines.Add("float alpha = 1.0;"); break; default: PixelLines.Add("float alpha = texColor.a;"); if (!stage.AlphaGen.Equals("1.0")) { PixelLines.Add("alpha = sin(g_time);"); } //PixelLines.Add("float alpha = sin(g_time);"); break; } if (stage.AlphaFunc != null) { switch (stage.AlphaFunc) { case "GT0": PixelLines.Add("if(alpha == 0.0) { discard; }"); break; case "LT128": PixelLines.Add("if(alpha >= 0.5) { discard; }"); break; case "GE128": PixelLines.Add("if(alpha < 0.5) { discard; }"); break; default: break; } } //PixelLines.Add("if(rgb.r < 0.1 && rgb.g < 0.1 && rgb.b < 0.1)"); //PixelLines.Add("alpha = 0;"); //PixelLines.Add("discard;"); PixelLines.Add("return float4(rgb, alpha);"); return(PixelLines); }
/// <summary> /// Renderizar escenario BSP utilizando matriz PVS para descartar clusters no visibles /// </summary> /// <param name="camPos">Posición actual de la camara</param> public void render(Vector3 camPos) { Device device = GuiController.Instance.D3dDevice; float elapsedTime = GuiController.Instance.ElapsedTime; time += elapsedTime; //Obtener leaf actual int actualLeaf = FindLeaf(camPos); //Obtener clusters visibles segun PVS int actualCluster = data.leafs[actualLeaf].cluster; if (actualCluster != antCluster) { antCluster = actualCluster; clusterVis.Clear(); for (int i = 0; i < data.leafs.Length; i++) { if (isClusterVisible(actualCluster, data.leafs[i].cluster)) { clusterVis.Add(i); } } } //Actualizar volumen del Frustum con nuevos valores de camara TgcFrustum frustum = GuiController.Instance.Frustum; frustum.updateVolume(device.Transform.View, device.Transform.Projection); foreach (int nleaf in clusterVis) { //Frustum Culling con el AABB del cluster TgcCollisionUtils.FrustumResult result = TgcCollisionUtils.classifyFrustumAABB(frustum, data.leafs[nleaf].boundingBox); if (result == TgcCollisionUtils.FrustumResult.OUTSIDE) { continue; } //Habilitar meshes de este leaf QLeaf currentLeaf = data.leafs[nleaf]; for (int i = currentLeaf.firstLeafSurface; i < currentLeaf.firstLeafSurface + currentLeaf.numLeafSurfaces; i++) { int iMesh = data.leafSurfaces[i]; TgcMesh mesh = meshes[iMesh]; if (mesh != null) { meshes[iMesh].Enabled = true; } } } //Renderizar meshes visibles mViewProj = device.Transform.View * device.Transform.Projection; for (int i = 0; i < meshes.Count; i++) { //Ignonar si no está habilitada TgcMesh mesh = meshes[i]; if (mesh == null || !mesh.Enabled) { continue; } QShaderData shader = data.shaderXSurface[i]; //Renderizado con shaders //TODO: Mejorar el renderizado de shaders. Por ahora esta deshabilitado if (shader != null && shader.Stages.Count > 0) { renderShaderMesh(mesh, shader); } //Renderizado normal else { //render mesh.render(); //deshabilitar para la proxima vuelta mesh.Enabled = false; } } }
/// <summary> /// Parsear shader /// </summary> private static QShaderData ParseShader(QShaderTokenizer tokenizer) { QShaderData qsd = new QShaderData(); qsd.Name = tokenizer.GetNext(); string token = tokenizer.GetNext(); if (!token.Equals("{")) { return null; } // Parse a shader while(!tokenizer.EOF) { token = tokenizer.GetNext().ToLower(); if(token.Equals("}")) { break; } switch (token) { case "{": QShaderStage stage = ParseStage(tokenizer); // I really really really don't like doing this, which basically just forces lightmaps to use the 'filter' blendmode // but if I don't a lot of textures end up looking too bright. I'm sure I'm jsut missing something, and this shouldn't // be needed. if(stage.IsLightMap() && (stage.HasBlendFunc)) { stage.BlendSrc = "GL_DST_COLOR"; stage.BlendDest = "GL_ZERO"; } // I'm having a ton of trouble getting lightingSpecular to work properly, // so this little hack gets it looking right till I can figure out the problem if(stage.AlphaGen.Equals("lightingspecular")) { stage.BlendSrc = "GL_ONE"; stage.BlendDest = "GL_ZERO"; stage.HasBlendFunc = false; stage.DepthWrite = true; } if(stage.HasBlendFunc) { qsd.Blend = true; } else { qsd.Opaque = true; } qsd.Stages.Add(stage); break; case "cull": qsd.Cull = tokenizer.GetNext(); break; case "deformvertexes": QShaderDeform deform = new QShaderDeform() {Type = tokenizer.GetNext().ToLower()}; switch(deform.Type) { case "wave": deform.Spread = 1.0f / ParserTools.ToFloat(tokenizer.GetNext()); deform.WaveForm = ParseWaveform(tokenizer); break; case "bulge": deform.BulgeWidth = ParserTools.ToFloat(tokenizer.GetNext()); deform.BulgeHeight = ParserTools.ToFloat(tokenizer.GetNext()); deform.BulgeSpeed = ParserTools.ToFloat(tokenizer.GetNext()); break; default: deform = null; break; } if(deform != null) { qsd.VertexDeforms.Add(deform); } break; case "sort": var sort = tokenizer.GetNext().ToLower(); switch(sort) { case "portal": qsd.Sort = 1; break; case "sky": qsd.Sort = 2; break; case "opaque": qsd.Sort = 3; break; case "banner": qsd.Sort = 6; break; case "underwater": qsd.Sort = 8; break; case "additive": qsd.Sort = 9; break; case "nearest": qsd.Sort = 16; break; default: qsd.Sort = int.Parse(sort); break; }; break; case "surfaceparm": var param = tokenizer.GetNext().ToLower(); switch(param) { case "sky": qsd.Sky = true; break; default: break; } break; default: break; } } if (qsd.Sort > 0) { qsd.Sort = (qsd.Opaque ? 3 : 9); } return qsd; }
private static List<string> BuildVertexShader(QShaderData shader, QShaderStage stage) { List<string> VertexLines = new List<string>(); VertexLines.Add("PSInput Out = In;"); VertexLines.Add("float4 defPosition = In.Pos;"); for(int i = 0; i < shader.VertexDeforms.Count; ++i) { QShaderDeform deform = shader.VertexDeforms[i]; switch(deform.Type) { case "wave": { string name = "deform" + i; string offName = "deformOff" + i; VertexLines.Add( "float " + offName + " = (In.Pos.x + In.Pos.y + In.Pos.z) * " + ParserTools.ToString(deform.Spread) + ";"); /*float phase = deform.WaveForm.Phase; //deform.WaveForm.Phase = phase.toFixed(4) + ' + ' + offName; <-----MIRAR ESTA LINEA VertexLines.Add(CreateWaveForm(name, deform.WaveForm, "g_time")); deform.WaveForm.Phase = phase;*/ //Parche temporal solo funciona con la funcion seno VertexLines.Add("float " + name + " = " + ParserTools.ToString(deform.WaveForm.Bas) + " + sin((" + ParserTools.ToString(deform.WaveForm.Phase) + " + " + "g_time" + " * " + ParserTools.ToString(deform.WaveForm.Freq) + " + " + offName + ") * 6.283) * " + ParserTools.ToString(deform.WaveForm.Amp) + ";"); //FIN parche VertexLines.Add("defPosition += float4(In.Normal * " + name + ",0);"); } break; case "bulge": { //float alpha = In.Tex0.x*bulgeWidth + g_time; //float deform = sin(alpha)*bulgeHeight; //defPosition += float4(In.Normal * deform0, 0); string deformi = "deform" + i; string alphai = "alpha" + i; VertexLines.Add("float " + alphai + " = In.Tex0.x*" + deform.BulgeWidth + " + g_time*" + deform.BulgeSpeed + ";"); VertexLines.Add("float " + deformi + " = sin(" + alphai + ")*" + deform.BulgeHeight + ";"); VertexLines.Add("defPosition += float4(In.Normal * " + deformi + ",0);"); } break; default: break; } } VertexLines.Add("float4 worldPosition = mul( defPosition, g_mWorld );"); VertexLines.Add("Out.Color = In.Color;"); if(stage.TcGen.Equals("environment")) { VertexLines.Add("float3 viewer = normalize(-worldPosition.xyz);"); VertexLines.Add("float d = dot(In.Normal, viewer);"); VertexLines.Add("float3 reflected = In.Normal*2.0*d - viewer;"); VertexLines.Add("Out.Tex0 = float2(0.5, 0.5) + reflected.xy * 0.5;"); } else { // Standard texturing VertexLines.Add("Out.Tex0 = In.Tex0;"); } // tcMods for(int i = 0; i < stage.TcMods.Count; ++i) { QTcMod tcMod = stage.TcMods[i]; switch(tcMod.Type) { case "rotate": VertexLines.Add("float r = " + ParserTools.ToString(tcMod.Angle) + " * g_time;"); VertexLines.Add("Out.Tex0 -= float2(0.5, 0.5);"); VertexLines.Add("Out.Tex0 = float2(Out.Tex0.x * cos(r) - Out.Tex0.y * sin(r), Out.Tex0.y * cos(r) + Out.Tex0.x * sin(r));"); VertexLines.Add("Out.Tex0 += float2(0.5, 0.5);"); break; case "scroll": VertexLines.Add( "Out.Tex0 += float2(" + ParserTools.ToString(tcMod.SSpeed) + " * g_time, " + ParserTools.ToString(tcMod.TSpeed) + " * g_time);"); break; case "scale": VertexLines.Add( "Out.Tex0 *= float2(" + ParserTools.ToString(tcMod.ScaleX) + ", " + ParserTools.ToString(tcMod.ScaleY) + ");" ); break; case "stretch": VertexLines.Add( CreateWaveForm("stretchWave", tcMod.WaveForm,"")); VertexLines.Add("stretchWave = 1.0 / stretchWave;"); VertexLines.Add("Out.Tex0 *= stretchWave;"); VertexLines.Add("Out.Tex0 += float2(0.5 - (0.5 * stretchWave), 0.5 - (0.5 * stretchWave));"); break; case "turb": var tName = "turbTime" + i; VertexLines.Add("float " + tName + " = " + ParserTools.ToString(tcMod.Turbulance.Phase) + " + g_time * " + ParserTools.ToString(tcMod.Turbulance.Freq) + ";"); VertexLines.Add("Out.Tex0.x += sin( ( ( In.Pos.x + In.Pos.z )* 1.0/128.0 * 0.125 + " + tName + " ) * 6.283) * " + ParserTools.ToString(tcMod.Turbulance.Amp) + ";"); VertexLines.Add("Out.Tex0.y += sin( ( In.Pos.y * 1.0/128.0 * 0.125 + " + tName + " ) * 6.283) * " + ParserTools.ToString(tcMod.Turbulance.Amp) + ";"); break; default: break; } } switch(stage.AlphaGen) { case "lightingspecular": VertexLines.Add("Out.Tex1 = In.Tex1;" ); break; default: break; } VertexLines.Add("Out.Pos = mul(worldPosition, g_mViewProj);"); VertexLines.Add("return Out;"); return VertexLines; }
private static List<string> BuildPixelShader(QShaderData shader, QShaderStage stage) { List<string> PixelLines = new List<string>(); PixelLines.Add("float4 texColor = tex2D(texture0, In.Tex0);"); switch(stage.RgbGen) { case "vertex": PixelLines.Add("float3 rgb = texColor.rgb * In.Color.rgb;"); break; case "wave": PixelLines.Add(CreateWaveForm("rgbWave", stage.RgbWaveform, "")); PixelLines.Add("float3 rgb = texColor.rgb * rgbWave;"); break; default: PixelLines.Add("float3 rgb = texColor.rgb;"); break; } switch(stage.AlphaGen) { case "wave": PixelLines.Add(CreateWaveForm("alpha", stage.AlphaWaveform, "")); //PixelLines.Add("alpha = sin(g_time);"); break; case "lightingspecular": // For now this is VERY special cased. May not work well with all instances of lightingSpecular PixelLines.Add("float4 light = tex2D(texture1, In.Tex1);"); PixelLines.Add("rgb *= light.rgb;"); PixelLines.Add("rgb += light.rgb * texColor.a * 0.6;"); // This was giving me problems, so I'm ignorning an actual specular calculation for now PixelLines.Add("float alpha = 1.0;"); break; default: PixelLines.Add("float alpha = texColor.a;"); if (!stage.AlphaGen.Equals("1.0")) PixelLines.Add("alpha = sin(g_time);"); //PixelLines.Add("float alpha = sin(g_time);"); break; } if(stage.AlphaFunc != null) { switch(stage.AlphaFunc) { case "GT0": PixelLines.Add("if(alpha == 0.0) { discard; }"); break; case "LT128": PixelLines.Add("if(alpha >= 0.5) { discard; }"); break; case "GE128": PixelLines.Add("if(alpha < 0.5) { discard; }"); break; default: break; } } //PixelLines.Add("if(rgb.r < 0.1 && rgb.g < 0.1 && rgb.b < 0.1)"); //PixelLines.Add("alpha = 0;"); //PixelLines.Add("discard;"); PixelLines.Add("return float4(rgb, alpha);"); return PixelLines; }
private static List<string> BuildEffectState(QShaderData shader, QShaderStage qstage) { List<string> StateLines = new List<string>(); StateLines.Add("AlphaBlendEnable = " + qstage.HasBlendFunc.ToString().ToLower() + ";"); StateLines.Add("SrcBlend = " + GLtoDXBlend(qstage.BlendSrc) + ";"); StateLines.Add("DestBlend = " + GLtoDXBlend(qstage.BlendDest) + ";"); //StateLines.Add("ZWriteEnable = " + (!qstage.HasBlendFunc).ToString().ToLower() + ";"); if (!shader.Cull.Equals("")) { if (shader.Cull.ToLower().Equals("disable")) { shader.Cull = "None"; } StateLines.Add("CullMode = " + shader.Cull + ";"); } return StateLines; }
public static string BuildShaderSource(QShaderData shader) { //devuelve el codigo del Fx ShaderCode shaderCode = new ShaderCode(); shaderCode.AuxFuntions.Add(CreateSquareFunction()); shaderCode.AuxFuntions.Add(CreateTriangleFunction()); shaderCode.VsStruct.Add("float4 Pos : POSITION;"); shaderCode.VsStruct.Add("float3 Normal : NORMAL;"); shaderCode.VsStruct.Add("float4 Color : COLOR;"); shaderCode.VsStruct.Add("float2 Tex0 : TEXCOORD0;"); shaderCode.VsStruct.Add("float2 Tex1 : TEXCOORD1;"); shaderCode.PsStruct.Add("float4 Pos : POSITION;"); shaderCode.PsStruct.Add("float3 Normal : NORMAL;"); shaderCode.PsStruct.Add("float4 Color : COLOR;"); shaderCode.PsStruct.Add("float2 Tex0 : TEXCOORD0;"); shaderCode.PsStruct.Add("float2 Tex1 : TEXCOORD1;"); shaderCode.Globals.Add("float4x4 g_mWorld;// : WORLD;"); shaderCode.Globals.Add("float4x4 g_mViewProj;// : VIEWPROJECTION;"); shaderCode.Globals.Add("float g_time;// : TIME;"); shaderCode.Globals.Add("sampler2D texture0 : register(s0);"); shaderCode.Globals.Add("sampler2D texture1 : register(s1);"); foreach (QShaderStage qstage in shader.Stages) { StageCode stageCode = shaderCode.NewStage(); stageCode.VertexLines = BuildVertexShader(shader, qstage); stageCode.PixelLines = BuildPixelShader(shader, qstage); stageCode.StatesLines = BuildEffectState(shader, qstage); } return shaderCode.Build(); }
//private bool first = true; /// <summary> /// Ejecuta el shader original de formato propio de Quake 3 convertido a una version similar de HLSL en DirectX. /// Estado experimental. Desabilitado por el momento. /// </summary> private void renderShaderMesh(TgcMesh mesh, QShaderData shader) { // if ((shader.Stages[0].HasBlendFunc) ^ (pass == 1)) // { //tiene es opaco se tiene que renderizar en la primer pasada //tiene alpha blending se tiene que renderizar en la segunda pasada // return; //} Device d3dDevice = GuiController.Instance.D3dDevice; Effect fx = shader.Fx; fx.Technique = "tec0"; fx.SetValue("g_mWorld", Matrix.Identity); fx.SetValue("g_mViewProj", mViewProj); fx.SetValue("g_time", time); TgcTexture originalTexture = null; if (mesh.DiffuseMaps != null) originalTexture = mesh.DiffuseMaps[0]; fx.Begin(FX.None); for (int j = 0; j < shader.Stages.Count; j++) { fx.BeginPass(j); if (shader.Stages[j].Textures.Count > 0) { mesh.DiffuseMaps[0] = shader.Stages[j].Textures[0]; } //mesh.render(); d3dDevice.SetTexture(0, mesh.DiffuseMaps[0].D3dTexture); if (mesh.LightMap != null) d3dDevice.SetTexture(1, mesh.LightMap.D3dTexture); else d3dDevice.SetTexture(1, null); mesh.D3dMesh.DrawSubset(0); fx.EndPass(); } fx.End(); if (mesh.DiffuseMaps != null) mesh.DiffuseMaps[0] = originalTexture; }