public static void AbsoluteWorldToWorld(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { // prior to version 2, always used position transform if (xform.version <= 1) { xform.type = ConversionType.Position; } switch (xform.type) { case ConversionType.Position: sb.AddLine(outputVariable, " = GetCameraRelativePositionWS(", inputValue, ");"); break; case ConversionType.Direction: case ConversionType.Normal: // both normal and direction are unchanged if (xform.normalize) { sb.AddLine(outputVariable, " = SafeNormalize(", inputValue, ");"); } else { sb.AddLine(outputVariable, " = ", inputValue, ";"); } break; } }
public static void TangentToWorld(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { // prior to version 2 all transforms were Normal, and directional transforms were normalized if (xform.version <= 1) { if (xform.type != ConversionType.Position) { xform.normalize = true; } xform.type = ConversionType.Normal; } using (sb.BlockScope()) { string tangentTransform = GenerateTangentTransform(sb, CoordinateSpace.World); switch (xform.type) { case ConversionType.Position: sb.AddLine(outputVariable, " = TransformTangentToWorldDir(", inputValue, ", ", tangentTransform, ", false).xyz + IN.WorldSpacePosition;"); break; case ConversionType.Direction: sb.AddLine(outputVariable, " = TransformTangentToWorldDir(", inputValue, ", ", tangentTransform, ", ", xform.NormalizeString(), ").xyz;"); break; case ConversionType.Normal: sb.AddLine(outputVariable, " = TransformTangentToWorld(", inputValue, ", ", tangentTransform, ", ", xform.NormalizeString(), ");"); break; } } }
public static void WorldToTangent(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { if (xform.version <= 1) { // prior to version 2, all transform were normalized, and all transforms were Normal transforms xform.normalize = true; xform.type = ConversionType.Normal; } using (sb.BlockScope()) { string tangentTransform = GenerateTangentTransform(sb, xform.from); switch (xform.type) { case ConversionType.Position: sb.AddLine(outputVariable, " = TransformWorldToTangentDir(", inputValue, " - IN.WorldSpacePosition, ", tangentTransform, ", false);"); break; case ConversionType.Direction: sb.AddLine(outputVariable, " = TransformWorldToTangentDir(", inputValue, ", ", tangentTransform, ", ", xform.NormalizeString(), ");"); break; case ConversionType.Normal: sb.AddLine(outputVariable, " = TransformWorldToTangent(", inputValue, ", ", tangentTransform, ", ", xform.NormalizeString(), ");"); break; } } }
public static void Identity(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { // identity didn't normalize before version 2 if ((xform.version > 1) && xform.normalize && (xform.type != ConversionType.Position)) { sb.AddLine(outputVariable, " = SafeNormalize(", inputValue, ");"); } else { sb.AddLine(outputVariable, " = ", inputValue, ";"); } }
public static string GenerateTangentTransform(ShaderStringBuilder sb, CoordinateSpace tangentTransformSpace) { sb.AddLine("$precision3x3 tangentTransform = $precision3x3(IN.", tangentTransformSpace.ToString(), "SpaceTangent, IN.", tangentTransformSpace.ToString(), "SpaceBiTangent, IN.", tangentTransformSpace.ToString(), "SpaceNormal);"); return("tangentTransform"); }
public static void ViewToWorld(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { switch (xform.type) { case ConversionType.Position: sb.AddLine(outputVariable, " = TransformViewToWorld(", inputValue, ");"); break; case ConversionType.Direction: if (xform.version <= 1) { xform.normalize = false; } sb.AddLine(outputVariable, " = TransformViewToWorldDir(", inputValue, ", ", xform.NormalizeString(), ");"); break; case ConversionType.Normal: sb.AddLine(outputVariable, " = TransformViewToWorldNormal(", inputValue, ", ", xform.NormalizeString(), ");"); break; } }
public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new[] { InputSlotId }, new[] { OutputSlotId }); string inputValue = $"{GetSlotValue(InputSlotId, generationMode)}.xyz"; string outputVariable = GetVariableNameForSlot(OutputSlotId); string outputType = FindOutputSlot <MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString(); // declare output variable and fill it out sb.AddLine(outputType, " ", outputVariable, ";"); SpaceTransformUtil.GenerateTransformCodeStatement(spaceTransform, inputValue, outputVariable, sb); }
private static void ViaWorld(SpaceTransform xform, string inputValue, string outputVariable, ShaderStringBuilder sb) { // should never be calling this if one of the spaces is already world space (silly, and could lead to infinite recursions) if ((xform.from == CoordinateSpace.World) || (xform.to == CoordinateSpace.World)) { return; } // this breaks the transform into two parts: (from->world) and (world->to) var toWorld = new SpaceTransform() { from = xform.from, to = CoordinateSpace.World, type = xform.type, normalize = false, version = xform.version }; var fromWorld = new SpaceTransform() { from = CoordinateSpace.World, to = xform.to, type = xform.type, normalize = xform.normalize, version = xform.version }; // Apply Versioning Hacks to match old (incorrect) versions if (xform.version <= 1) { if (xform.type == ConversionType.Direction) { switch (xform.from) { case CoordinateSpace.AbsoluteWorld: if ((xform.to == CoordinateSpace.Object) || (xform.to == CoordinateSpace.View)) { // these transforms were wrong in v0, but correct in v1, so here we // pretend it is a later version to disable the v1 versioning in the AbsWorldToWorld transform if (xform.version == 1) { toWorld.version = 2; } } break; case CoordinateSpace.View: if ((xform.to == CoordinateSpace.Tangent) || (xform.to == CoordinateSpace.AbsoluteWorld)) { // these transforms erroneously used the position view-to-world transform toWorld.type = ConversionType.Position; } break; case CoordinateSpace.Tangent: if ((xform.to == CoordinateSpace.Object) || (xform.to == CoordinateSpace.View) || (xform.to == CoordinateSpace.AbsoluteWorld)) { // manually version to 2, to remove normalization (while keeping Normal type) toWorld.type = ConversionType.Normal; toWorld.version = 2; } break; } } } using (sb.BlockScope()) { sb.AddLine("// Converting ", xform.type.ToString(), " from ", xform.from.ToString(), " to ", xform.to.ToString(), " via world space"); sb.AddLine("float3 world;"); GenerateTransformCodeStatement(toWorld, inputValue, "world", sb); GenerateTransformCodeStatement(fromWorld, "world", outputVariable, sb); } }