Skip to content

Commit

Permalink
add ability to use texture tiling and offset on texture2ds (#4185)
Browse files Browse the repository at this point in the history
* add ability to use texture tiling and offset on texture2ds

* minor code review fixes and adding SplitTextureTransformNode

* more code review notes and minor bugfixes

* more code review changes and bump subgraph version for reimport

* formatting

* fixing a bug with the parallax occlusion mapping node, and changing the title of the split texture transform node

* fixing node name

* make normalfromtexture use tiling correctly, and added copy support for the use tiling flag

* formatting

* fixing bad merge

* fixing more bad merges and a bug I noticed while reviewing output code

* Update CHANGELOG.md
  • Loading branch information
elizabeth-legros authored Apr 30, 2021
1 parent 71761d8 commit 65776ae
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 9 deletions.
3 changes: 3 additions & 0 deletions com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ struct UnityTexture2D
float4 SampleBias(UnitySamplerState s, float2 uv, float bias) { return SAMPLE_TEXTURE2D_BIAS(tex, s.samplerstate, uv, bias); }
float4 SampleGrad(UnitySamplerState s, float2 uv, float2 dpdx, float2 dpdy) { return SAMPLE_TEXTURE2D_GRAD(tex, s.samplerstate, uv, dpdx, dpdy); }

float2 GetTransformedUV(float2 uv) { return uv * scaleTranslate.xy + scaleTranslate.zw; }

#ifndef SHADER_API_GLES
float CalculateLevelOfDetail(UnitySamplerState s, float2 uv) { return CALCULATE_TEXTURE2D_LOD(tex, s.samplerstate, uv); }

Expand Down Expand Up @@ -92,6 +94,7 @@ UnityTexture2D UnityBuildTexture2DStructInternal(TEXTURE2D_PARAM(tex, samplersta
return result;
}


struct UnityTexture2DArray
{
TEXTURE2D_ARRAY(tex);
Expand Down
3 changes: 3 additions & 0 deletions com.unity.shadergraph/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added `Use Custom Binding` option to properties. When this option is enabled, a property can be connected to a `Branch On Input Connection` node. The user provides a custom label that will be displayed on the exposed property, when it is disconnected in a graph.
- Added new dropdown property type for subgraphs, to allow compile time branching that can be controlled from the parent graph, via the subgraph instance node.
- Added `Dropdown` node per dropdown property, that can be used to configure the desired branch control.
- Added the ability to mark textures / colors as \[MainTexture\] and \[MainColor\].
- Added the ability to enable tiling and offset controls for a Texture2D input.
- Added the Split Texture Transform node to allow using/overriding the provided tiling and offset from a texture input.

### Changed
- Updated/corrected View Direction doc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,16 @@ internal Texture2DShaderProperty()

internal string modifiableTagString => modifiable ? "" : "[NonModifiableTextureData]";

[SerializeField]
internal bool useTilingAndOffset = false;

internal string useSTString => useTilingAndOffset ? "" : "[NoScaleOffset]";
internal string mainTextureString => isMainTexture ? "[MainTexture]" : "";

internal override string GetPropertyBlockString()
{
var normalTagString = (defaultType == DefaultType.NormalMap) ? "[Normal]" : "";
return $"{hideTagString}{modifiableTagString}{normalTagString}{mainTextureString}[NoScaleOffset]{referenceName}(\"{displayName}\", 2D) = \"{ToShaderLabString(defaultType)}\" {{}}";
return $"{hideTagString}{modifiableTagString}{normalTagString}{mainTextureString}{useSTString}{referenceName}(\"{displayName}\", 2D) = \"{ToShaderLabString(defaultType)}\" {{}}";
}

// Texture2D properties cannot be set via Hybrid path at the moment; disallow that choice
Expand All @@ -64,7 +68,10 @@ internal override void ForeachHLSLProperty(Action<HLSLProperty> action)
action(new HLSLProperty(HLSLType._Texture2D, referenceName, HLSLDeclaration.Global));
action(new HLSLProperty(HLSLType._SamplerState, "sampler" + referenceName, HLSLDeclaration.Global));
action(new HLSLProperty(HLSLType._float4, referenceName + "_TexelSize", decl));
// action(new HLSLProperty(HLSLType._float4, referenceName + "_ST", decl)); // TODO: allow users to make use of the ST values
if (useTilingAndOffset)
{
action(new HLSLProperty(HLSLType._float4, referenceName + "_ST", decl));
}
}

internal override string GetPropertyAsArgumentString(string precisionString)
Expand All @@ -82,7 +89,16 @@ internal override string GetHLSLVariableName(bool isSubgraphProperty)
if (isSubgraphProperty)
return referenceName;
else
return $"UnityBuildTexture2DStructNoScale({referenceName})";
{
if (useTilingAndOffset)
{
return $"UnityBuildTexture2DStruct({referenceName})";
}
else
{
return $"UnityBuildTexture2DStructNoScale({referenceName})";
}
}
}

[SerializeField]
Expand Down Expand Up @@ -125,6 +141,7 @@ internal override ShaderInput Copy()
displayName = displayName,
value = value,
defaultType = defaultType,
useTilingAndOffset = useTilingAndOffset,
isMainTexture = isMainTexture
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo
samplerValue = textureValue;

sb.AppendLine("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToShaderString(), GetVariableNameForSlot(OutputSlotId));
sb.AppendLine("{0}(TEXTURE2D_ARGS({1}.tex, {2}.samplerstate), {3}, {4}, {5}, {6});", GetFunctionName(), textureValue, samplerValue, uvValue, offsetValue, strengthValue, outputValue);
sb.AppendLine("{0}(TEXTURE2D_ARGS({1}.tex, {2}.samplerstate), {1}.GetTransformedUV({3}), {4}, {5}, {6});", GetFunctionName(), textureValue, samplerValue, uvValue, offsetValue, strengthValue, outputValue);
}

public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode gene
}
sb.AppendLine("#else");
{
var result = string.Format(" $precision4 {0} = SAMPLE_TEXTURE2D_LOD({1}.tex, {2}.samplerstate, {3}, {4});"
var result = string.Format(" $precision4 {0} = SAMPLE_TEXTURE2D_LOD({1}.tex, {2}.samplerstate, {1}.GetTransformedUV({3}), {4});"
, GetVariableNameForSlot(OutputSlotRGBAId)
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInputId, generationMode) : id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode gene
var edgesSampler = owner.GetEdges(samplerSlot.slotReference);

var id = GetSlotValue(TextureInputId, generationMode);
var result = string.Format("$precision4 {0} = SAMPLE_TEXTURE2D({1}.tex, {2}.samplerstate, {3});"

var result = string.Format("$precision4 {0} = SAMPLE_TEXTURE2D({1}.tex, {2}.samplerstate, {1}.GetTransformedUV({3}));"
, GetVariableNameForSlot(OutputSlotRGBAId)
, id
, edgesSampler.Any() ? GetSlotValue(SamplerInput, generationMode) : id
Expand All @@ -129,6 +130,8 @@ public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode gene
}

sb.AppendLine(string.Format("$precision {0} = {1}.r;", GetVariableNameForSlot(OutputSlotRId), GetVariableNameForSlot(OutputSlotRGBAId)));


sb.AppendLine(string.Format("$precision {0} = {1}.g;", GetVariableNameForSlot(OutputSlotGId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.b;", GetVariableNameForSlot(OutputSlotBId), GetVariableNameForSlot(OutputSlotRGBAId)));
sb.AppendLine(string.Format("$precision {0} = {1}.a;", GetVariableNameForSlot(OutputSlotAId), GetVariableNameForSlot(OutputSlotRGBAId)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo
var amplitude = GetSlotValue(kAmplitudeSlotId, generationMode);
var uvs = GetSlotValue(kUVsSlotId, generationMode);

sb.AppendLines(String.Format(@"$precision2 {5} = {4} + ParallaxMapping(TEXTURE2D_ARGS({0}.tex, {1}.samplerstate), IN.{2}, {3} * 0.01, {4});",
sb.AppendLines(String.Format(@"$precision2 {5} = {0}.GetTransformedUV({4}) + ParallaxMapping(TEXTURE2D_ARGS({0}.tex, {1}.samplerstate), IN.{2}, {3} * 0.01, {0}.GetTransformedUV({4}));",
heightmap,
edgesSampler.Any() ? GetSlotValue(kHeightmapSamplerSlotId, generationMode) : heightmap,
CoordinateSpace.Tangent.ToVariableName(InterpolatorType.ViewDirection),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo
$precision3 {tmpViewDirUV} = normalize($precision3({tmpViewDir}.xy * {tmpMaxHeight}, {tmpViewDir}.z)); // TODO: skip normalize
PerPixelHeightDisplacementParam {tmpPOMParam};
{tmpPOMParam}.uv = {uvs};");
{tmpPOMParam}.uv = {heightmap}.GetTransformedUV({uvs});");

// to avoid crashes when steps gets too big, and
// to avoid divide by zero, we clamp it to the range [1, 256]
Expand All @@ -173,7 +173,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo

sb.AppendLines($@"
$precision {tmpOutHeight};
$precision2 {GetVariableNameForSlot(kParallaxUVsOutputSlotId)} = {uvs} + ParallaxOcclusionMapping{GetFunctionName()}({lod}, {lodThreshold}, {steps}, {tmpViewDirUV}, {tmpPOMParam}, {tmpOutHeight}, TEXTURE2D_ARGS({heightmap}.tex, {sampler}.samplerstate));
$precision2 {GetVariableNameForSlot(kParallaxUVsOutputSlotId)} = {heightmap}.GetTransformedUV({uvs}) + ParallaxOcclusionMapping{GetFunctionName()}({lod}, {lodThreshold}, {steps}, {tmpViewDirUV}, {tmpPOMParam}, {tmpOutHeight}, TEXTURE2D_ARGS({heightmap}.tex, {sampler}.samplerstate));
$precision {GetVariableNameForSlot(kPixelDepthOffsetOutputSlotId)} = ({tmpMaxHeight} - {tmpOutHeight} * {tmpMaxHeight}) / max({tmpNdotV}, 0.0001);
");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Reflection;
using UnityEngine;

namespace UnityEditor.ShaderGraph
{
[Title("Input", "Texture", "Split Texture Transform")]
class SplitTextureTransformNode : CodeFunctionNode
{
public override bool hasPreview { get { return false; } }
public SplitTextureTransformNode()
{
name = "Split Texture Transform";
}

protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_SplitTextureTransform", BindingFlags.Static | BindingFlags.NonPublic);
}

static string Unity_SplitTextureTransform(
[Slot(0, Binding.None)] Texture2D In,
[Slot(1, Binding.None)] out Vector2 Tiling,
[Slot(2, Binding.None)] out Vector2 Offset,
[Slot(3, Binding.None)] out Texture2D TextureOnly)
{
TextureOnly = default;
Tiling = default;
Offset = default;
return
@"
{
TextureOnly = In;
TextureOnly.scaleTranslate = float4(1.0f, 1.0f, 0.0f, 0.0f);
Tiling = In.scaleTranslate.xy;
Offset = In.scaleTranslate.zw;
}
";
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,20 @@ out var texture2DField
out var textureModeField));

textureModeField.SetEnabled(texture2DProperty.generatePropertyBlock);

var togglePropertyDrawer = new ToggleDataPropertyDrawer();
propertySheet.Add(togglePropertyDrawer.CreateGUI(
newValue =>
{
this._preChangeValueCallback("Change Use Tilling and Offset");
if (texture2DProperty.useTilingAndOffset == newValue.isOn)
return;
texture2DProperty.useTilingAndOffset = newValue.isOn;
this._postChangeValueCallback();
},
new ToggleData(texture2DProperty.useTilingAndOffset, true),
"Use Tiling and Offset",
out var tilingAndOffsetToggle));
}
}

Expand Down

0 comments on commit 65776ae

Please sign in to comment.