|
|
|
|
|
|
ShaderGraphRequirements vertexRequirements, |
|
|
|
CoordinateSpace preferredCoordinateSpace) |
|
|
|
{ |
|
|
|
// ----------------------------------------------------- //
|
|
|
|
// SETUP //
|
|
|
|
// ----------------------------------------------------- //
|
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Tangent space requires going via World space
|
|
|
|
|
|
|
|
// step 1:
|
|
|
|
// *generate needed interpolators
|
|
|
|
// *generate output from the vertex shader that writes into these interpolators
|
|
|
|
// *generate the pixel shader code that declares needed variables in the local scope
|
|
|
|
// -------------------------------------
|
|
|
|
// Generate combined graph requirements
|
|
|
|
|
|
|
|
int interpolatorIndex = interpolatorStartIndex; |
|
|
|
int interpolatorIndex = interpolatorStartIndex; |
|
|
|
// ----------------------------------------------------- //
|
|
|
|
// GENERATE VERTEX > PIXEL PIPELINE //
|
|
|
|
// ----------------------------------------------------- //
|
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// If any stage requires component write into vertex stage
|
|
|
|
// If model or pixel requires component write into interpolators and pixel stage
|
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Position
|
|
|
|
|
|
|
|
if (combinedRequirements.requiresPosition > 0) |
|
|
|
{ |
|
|
|
var name = preferredCoordinateSpace.ToVariableName(InterpolatorType.Position); |
|
|
|
var preferredSpacePosition = ConvertBetweenSpace("v.vertex", CoordinateSpace.Object, preferredCoordinateSpace, InputType.Position); |
|
|
|
vertexShader.AppendLine("float3 {0} = {1};", name, preferredSpacePosition); |
|
|
|
if (graphModelRequirements.requiresPosition > 0) |
|
|
|
{ |
|
|
|
vertexOutputStruct.AppendLine("float3 {0} : TEXCOORD{1};", name, interpolatorIndex); |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = {0};", name); |
|
|
|
pixelShader.AppendLine("float3 {0} = IN.{0};", name); |
|
|
|
interpolatorIndex++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Normal
|
|
|
|
// Bitangent needs Normal for x product
|
|
|
|
// bitangent needs normal for x product
|
|
|
|
//if (vertexRequirements.requiresNormal > 0 || vertexRequirements.requiresBitangent > 0)
|
|
|
|
// vertexDescriptionInputs.AppendLine("vdi.{0} = {0};", name);
|
|
|
|
if (graphModelRequirements.requiresNormal > 0 || graphModelRequirements.requiresBitangent > 0) |
|
|
|
{ |
|
|
|
vertexOutputStruct.AppendLine("float3 {0} : TEXCOORD{1};", name, interpolatorIndex); |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Tangent
|
|
|
|
|
|
|
|
//if (vertexRequirements.requiresTangent > 0 || vertexRequirements.requiresBitangent > 0)
|
|
|
|
// vertexDescriptionInputs.AppendLine("vdi.{0} = {0};", name);
|
|
|
|
if (graphModelRequirements.requiresTangent > 0 || graphModelRequirements.requiresBitangent > 0) |
|
|
|
{ |
|
|
|
vertexOutputStruct.AppendLine("float3 {0} : TEXCOORD{1};", name, interpolatorIndex); |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Bitangent
|
|
|
|
|
|
|
|
if (combinedRequirements.requiresBitangent > 0) |
|
|
|
{ |
|
|
|
|
|
|
preferredCoordinateSpace.ToVariableName(InterpolatorType.Normal), |
|
|
|
preferredCoordinateSpace.ToVariableName(InterpolatorType.Tangent), |
|
|
|
"v.tangent.w"); |
|
|
|
//if (vertexRequirements.requiresBitangent > 0)
|
|
|
|
// vertexDescriptionInputs.AppendLine("vdi.{0} = {0};", name);
|
|
|
|
if (graphModelRequirements.requiresBitangent > 0) |
|
|
|
{ |
|
|
|
vertexOutputStruct.AppendLine("float3 {0} : TEXCOORD{1};", name, interpolatorIndex); |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// View Direction
|
|
|
|
|
|
|
|
if (vertexRequirements.requiresViewDir > 0) |
|
|
|
vertexShaderDescriptionInputs.AppendLine("vdi.{0} = {1};", name, preferredSpaceViewDir); |
|
|
|
vertexShader.AppendLine("float3 {0} = {1};", name, preferredSpaceViewDir); |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = {1};", name, preferredSpaceViewDir); |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = {0};", name); |
|
|
|
if (combinedRequirements.requiresPosition > 0) |
|
|
|
{ |
|
|
|
var name = preferredCoordinateSpace.ToVariableName(InterpolatorType.Position); |
|
|
|
var preferredSpacePosition = ConvertBetweenSpace("v.vertex", CoordinateSpace.Object, preferredCoordinateSpace, InputType.Position); |
|
|
|
if (vertexRequirements.requiresPosition > 0) |
|
|
|
vertexShader.AppendLine("float3 {0} = {1};", name, preferredSpacePosition); |
|
|
|
if (graphModelRequirements.requiresPosition > 0) |
|
|
|
{ |
|
|
|
vertexOutputStruct.AppendLine("float3 {0} : TEXCOORD{1};", name, interpolatorIndex); |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = {1}.xyz;", name, preferredSpacePosition); |
|
|
|
pixelShader.AppendLine("float3 {0} = IN.{0};", name); |
|
|
|
interpolatorIndex++; |
|
|
|
} |
|
|
|
} |
|
|
|
// -------------------------------------
|
|
|
|
// Tangent space transform matrix
|
|
|
|
|
|
|
|
if (combinedRequirements.NeedsTangentSpace()) |
|
|
|
{ |
|
|
|
|
|
|
tangent, bitangent, normal); |
|
|
|
} |
|
|
|
|
|
|
|
// Generate the space translations needed by the vertex description
|
|
|
|
{ |
|
|
|
//var sg = new ShaderGenerator();
|
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresNormal, InterpolatorType.Normal, preferredCoordinateSpace, |
|
|
|
InputType.Normal, vertexShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresTangent, InterpolatorType.Tangent, preferredCoordinateSpace, |
|
|
|
InputType.Vector, vertexShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresBitangent, InterpolatorType.BiTangent, preferredCoordinateSpace, |
|
|
|
InputType.Vector, vertexShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresViewDir, InterpolatorType.ViewDirection, preferredCoordinateSpace, |
|
|
|
InputType.Vector, vertexShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresPosition, InterpolatorType.Position, preferredCoordinateSpace, |
|
|
|
InputType.Position, vertexShader, Dimension.Three); |
|
|
|
//vertexShader.AppendLines(sg.GetShaderString(0));
|
|
|
|
} |
|
|
|
// -------------------------------------
|
|
|
|
// Vertex Color
|
|
|
|
// Generate the space translations needed by the surface description and model
|
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresNormal, InterpolatorType.Normal, preferredCoordinateSpace, |
|
|
|
InputType.Normal, pixelShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresTangent, InterpolatorType.Tangent, preferredCoordinateSpace, |
|
|
|
InputType.Vector, pixelShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresBitangent, InterpolatorType.BiTangent, preferredCoordinateSpace, |
|
|
|
InputType.Vector, pixelShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresViewDir, InterpolatorType.ViewDirection, preferredCoordinateSpace, |
|
|
|
InputType.Vector, pixelShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresPosition, InterpolatorType.Position, preferredCoordinateSpace, |
|
|
|
InputType.Position, pixelShader, Dimension.Three); |
|
|
|
|
|
|
|
if (vertexRequirements.requiresVertexColor) |
|
|
|
vertexShaderDescriptionInputs.AppendLine("vdi.{0} = v.color;", ShaderGeneratorNames.VertexColor); |
|
|
|
if (graphModelRequirements.requiresVertexColor) |
|
|
|
{ |
|
|
|
var vertexColor = "v.color"; |
|
|
|
vertexShader.AppendLine("float4 {0} = {1};", ShaderGeneratorNames.VertexColor, vertexColor); |
|
|
|
if (graphModelRequirements.requiresVertexColor) |
|
|
|
{ |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = v.color;", ShaderGeneratorNames.VertexColor); |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = {0};", ShaderGeneratorNames.VertexColor); |
|
|
|
/*if (combinedRequirements.requiresScreenPosition) |
|
|
|
{ |
|
|
|
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false); |
|
|
|
vertexOutputs.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(mul(GetWorldToHClipMatrix(), mul(GetObjectToWorldMatrix(), v.vertex)), _ProjectionParams.x);", ShaderGeneratorNames.ScreenPosition), false); |
|
|
|
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false); |
|
|
|
interpolatorIndex++; |
|
|
|
}*/ |
|
|
|
// -------------------------------------
|
|
|
|
// Screen Position
|
|
|
|
if (vertexRequirements.requiresScreenPosition) |
|
|
|
{ |
|
|
|
vertexShaderDescriptionInputs.AppendLine("vdi.{0} = {0};", ShaderGeneratorNames.ScreenPosition); |
|
|
|
} |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = {1};", ShaderGeneratorNames.ScreenPosition, screenPosition); |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = {0};", ShaderGeneratorNames.ScreenPosition); |
|
|
|
foreach (var channel in vertexRequirements.requiresMeshUVs.Distinct()) |
|
|
|
{ |
|
|
|
vertexShaderDescriptionInputs.AppendLine("vdi.{0} = v.texcoord{1};", channel.GetUVName(), (int)channel); |
|
|
|
} |
|
|
|
// -------------------------------------
|
|
|
|
// UV
|
|
|
|
|
|
|
|
foreach (var channel in combinedRequirements.requiresMeshUVs.Distinct()) |
|
|
|
vertexShader.AppendLine("float4 {0} = v.texcoord{1};", channel.GetUVName(), (int)channel); |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = v.texcoord{1};", channel.GetUVName(), (int)channel); |
|
|
|
vertexShaderOutputs.AppendLine("o.{0} = {0};", channel.GetUVName()); |
|
|
|
// step 2
|
|
|
|
// copy the locally defined values into the surface description
|
|
|
|
// structure using the requirements for ONLY the shader graph
|
|
|
|
// ----------------------------------------------------- //
|
|
|
|
// TRANSLATE NEEDED SPACES //
|
|
|
|
// ----------------------------------------------------- //
|
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Generate the space translations needed by the vertex description
|
|
|
|
|
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresNormal, InterpolatorType.Normal, preferredCoordinateSpace, |
|
|
|
InputType.Normal, vertexShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresTangent, InterpolatorType.Tangent, preferredCoordinateSpace, |
|
|
|
InputType.Vector, vertexShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresBitangent, InterpolatorType.BiTangent, preferredCoordinateSpace, |
|
|
|
InputType.Vector, vertexShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresViewDir, InterpolatorType.ViewDirection, preferredCoordinateSpace, |
|
|
|
InputType.Vector, vertexShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(vertexRequirements.requiresPosition, InterpolatorType.Position, preferredCoordinateSpace, |
|
|
|
InputType.Position, vertexShader, Dimension.Three); |
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Generate the space translations needed by the surface description and model
|
|
|
|
|
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresNormal, InterpolatorType.Normal, preferredCoordinateSpace, |
|
|
|
InputType.Normal, pixelShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresTangent, InterpolatorType.Tangent, preferredCoordinateSpace, |
|
|
|
InputType.Vector, pixelShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresBitangent, InterpolatorType.BiTangent, preferredCoordinateSpace, |
|
|
|
InputType.Vector, pixelShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresViewDir, InterpolatorType.ViewDirection, preferredCoordinateSpace, |
|
|
|
InputType.Vector, pixelShader, Dimension.Three); |
|
|
|
GenerateSpaceTranslations(graphModelRequirements.requiresPosition, InterpolatorType.Position, preferredCoordinateSpace, |
|
|
|
InputType.Position, pixelShader, Dimension.Three); |
|
|
|
|
|
|
|
// ----------------------------------------------------- //
|
|
|
|
// START SURFACE DESCRIPTION //
|
|
|
|
// ----------------------------------------------------- //
|
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Copy the locally defined values into the surface description
|
|
|
|
// structure using the requirements for ONLY the shader graph pixel stage
|
|
|
|
|
|
|
|
{ |
|
|
|
var replaceString = "surfaceInput.{0} = {0};"; |
|
|
|
GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresNormal, InterpolatorType.Normal, pixelShaderSurfaceInputs, replaceString); |
|
|
|
|
|
|
GenerateSpaceTranslationSurfaceInputs(surfaceRequirements.requiresPosition, InterpolatorType.Position, pixelShaderSurfaceInputs, replaceString); |
|
|
|
} |
|
|
|
|
|
|
|
if (pixelRequirements.requiresVertexColor) |
|
|
|
pixelShaderSurfaceInputs.AppendLine("surfaceInput.{0} = {0};", ShaderGeneratorNames.VertexColor); |
|
|
|
|
|
|
|
|
|
|
foreach (var channel in pixelRequirements.requiresMeshUVs.Distinct()) |
|
|
|
pixelShaderSurfaceInputs.AppendLine("surfaceInput.{0} = {0};", ShaderGeneratorNames.GetUVName(channel)); |
|
|
|
|
|
|
|
// ----------------------------------------------------- //
|
|
|
|
// START VERTEX DESCRIPTION //
|
|
|
|
// ----------------------------------------------------- //
|
|
|
|
|
|
|
|
// -------------------------------------
|
|
|
|
// Copy the locally defined values into the vertex description
|
|
|
|
// structure using the requirements for ONLY the shader graph vertex stage
|
|
|
|
// additional requirements have come from the lighting model
|
|
|
|
// and are not needed in the shader graph
|
|
|
|
|
|
|
|
{ |
|
|
|
var replaceString = "vdi.{0} = {0};"; |
|
|
|
GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresNormal, InterpolatorType.Normal, vertexShaderDescriptionInputs, replaceString); |
|
|
|
|
|
|
GenerateSpaceTranslationSurfaceInputs(vertexRequirements.requiresPosition, InterpolatorType.Position, vertexShaderDescriptionInputs, replaceString); |
|
|
|
} |
|
|
|
|
|
|
|
if (vertexRequirements.requiresVertexColor) |
|
|
|
vertexShaderDescriptionInputs.AppendLine("vdi.{0} = {0};", ShaderGeneratorNames.VertexColor); |
|
|
|
|
|
|
|
if (vertexRequirements.requiresScreenPosition) |
|
|
|
vertexShaderDescriptionInputs.AppendLine("vdi.{0} = {0};", ShaderGeneratorNames.ScreenPosition); |
|
|
|
|
|
|
|
foreach (var channel in vertexRequirements.requiresMeshUVs.Distinct()) |
|
|
|
vertexShaderDescriptionInputs.AppendLine("vdi.{0} = {0};", channel.GetUVName(), (int)channel); |
|
|
|
} |
|
|
|
|
|
|
|
public enum Dimension |
|
|
|
|
|
|
struct GraphVertexOutput |
|
|
|
{ |
|
|
|
float4 position : POSITION; |
|
|
|
${Interpolators} |
|
|
|
${Interpolators} |
|
|
|
}; |
|
|
|
|
|
|
|
GraphVertexOutput vert (GraphVertexInput v) |
|
|
|
|
|
|
GraphVertexOutput o; |
|
|
|
float3 positionWS = TransformObjectToWorld(v.vertex); |
|
|
|
o.position = TransformWorldToHClip(positionWS); |
|
|
|
${VertexShader} |
|
|
|
${VertexShader} |
|
|
|
${LocalPixelShader} |
|
|
|
${LocalPixelShader} |
|
|
|
${SurfaceInputs} |
|
|
|
${SurfaceInputs} |
|
|
|
${SurfaceOutputRemap} |
|
|
|
${SurfaceOutputRemap} |
|
|
|
} |
|
|
|
ENDHLSL |
|
|
|
} |
|
|
|