Тайлинг и оффсет текстуры в шейдере сбрасывается при смене окна

Рейтинг: 0Ответов: 1Опубликовано: 05.05.2023

В моем шейдере (CG/hlsl) есть текстура которую я устанавливаю со скрипта. Для нее определен параметр в начале (_GrassMap), так же параметры sampler2D _GrassMap в cg блоке и такой же float4 с приставкой _ST.

И все вроде хорошо работает до того момента как я не сменю активное окно в виндовс на другое. В этот момент как по магии значения тайлинга и оффсета для текстуры сбрасываются до тех, что были в префабе с материалом этого шейдера.

Что это такое и как это вылечить?

Properties
{
    [Header(Shading)]
    _TopColor("Top Color", Color) = (1,1,1,1)
    _BottomColor("Bottom Color", Color) = (1,1,1,1)
    _TranslucentGain("Translucent Gain", Range(0,1)) = 0.5
    [Space]
    _TessellationUniform ("Tessellation Uniform", Range(1, 64)) = 1
    [Header(Blades)]
    _BladeWidth("Blade Width", Float) = 0.05
    _BladeWidthRandom("Blade Width Random", Float) = 0.02
    _BladeHeight("Blade Height", Float) = 0.5
    _BladeHeightRandom("Blade Height Random", Float) = 0.3
    _BladeForward("Blade Forward Amount", Float) = 0.38
    _BladeCurve("Blade Curvature Amount", Range(1, 4)) = 2
    _BendRotationRandom("Bend Rotation Random", Range(0, 1)) = 0.2
    [Header(Wind)]
    _WindDistortionMap("Wind Distortion Map", 2D) = "white" {}
    _WindStrength("Wind Strength", Float) = 1
    _WindFrequency("Wind Frequency", Vector) = (0.05, 0.05, 0, 0)
    [Header(Maps)]
    _GrassMap("Grass Map", 2D) = "black" {}
    _GrassTreshold("Grass Treshold", Float) = 0.5
    [Header(Rendering)]
    _RenderDistance("Render Distance", Float) = 70.0
    _RenderSmoothingDistance("Render Smoothing Distance", Float) = 20.0
}

CGINCLUDE
#include "UnityCG.cginc"
#include "Autolight.cginc"
#include "Assets/Resources/Grass/CustomTessellation.cginc"

struct geometryOutput
{
    float4 pos : SV_POSITION;
#if UNITY_PASS_FORWARDBASE      
    float3 normal : NORMAL;
    float2 uv : TEXCOORD0;
    // unityShadowCoord4 is defined as a float4 in UnityShadowLibrary.cginc.
    unityShadowCoord4 _ShadowCoord : TEXCOORD1;
#endif
};

// Simple noise function, sourced from http://answers.unity.com/answers/624136/view.html
// Extended discussion on this function can be found at the following link:
// https://forum.unity.com/threads/am-i-over-complicating-this-random-function.454887/#post-2949326
// Returns a number in the 0...1 range.
float rand(float3 co)
{
    return frac(sin(dot(co.xyz, float3(12.9898, 78.233, 53.539))) * 43758.5453);
}

// Construct a rotation matrix that rotates around the provided axis, sourced from:
// https://gist.github.com/keijiro/ee439d5e7388f3aafc5296005c8c3f33
float3x3 AngleAxis3x3(float angle, float3 axis)
{
    float c, s;
    sincos(angle, s, c);

    float t = 1 - c;
    float x = axis.x;
    float y = axis.y;
    float z = axis.z;

    return float3x3(
        t * x * x + c, t * x * y - s * z, t * x * z + s * y,
        t * x * y + s * z, t * y * y + c, t * y * z - s * x,
        t * x * z - s * y, t * y * z + s * x, t * z * z + c
        );
}

geometryOutput VertexOutput(float3 pos, float3 normal, float2 uv)
{
    geometryOutput o;

    o.pos = UnityObjectToClipPos(pos);

#if UNITY_PASS_FORWARDBASE
    o.normal = UnityObjectToWorldNormal(normal);
    o.uv = uv;
    // Shadows are sampled from a screen-space shadow map texture.
    o._ShadowCoord = ComputeScreenPos(o.pos);
#elif UNITY_PASS_SHADOWCASTER
    // Applying the bias prevents artifacts from appearing on the surface.
    o.pos = UnityApplyLinearShadowBias(o.pos);
#endif

    return o;
}

geometryOutput GenerateGrassVertex(float3 vertexPosition, float width, float height, float forward, float2 uv, float3x3 transformMatrix)
{
    float3 tangentPoint = float3(width, forward, height);

    float3 tangentNormal = normalize(float3(0, -1, forward));

    float3 localPosition = vertexPosition + mul(transformMatrix, tangentPoint);
    float3 localNormal = mul(transformMatrix, tangentNormal);
    return VertexOutput(localPosition, localNormal, uv);
}

float _BladeHeight;
float _BladeHeightRandom;

float _BladeWidthRandom;
float _BladeWidth;

float _BladeForward;
float _BladeCurve;

float _BendRotationRandom;

sampler2D _WindDistortionMap;
float4 _WindDistortionMap_ST;

float _WindStrength;
float2 _WindFrequency;

sampler2D _GrassMap;
float4 _GrassMap_ST;
float _GrassTreshold;

float _RenderDistance;
float _RenderSmoothingDistance;

#define BLADE_SEGMENTS 2

// Geometry program that takes in a single triangle and outputs a blade
// of grass at that triangle first vertex position, aligned to the vertex's normal.
[maxvertexcount(BLADE_SEGMENTS * 2 + 1)]
void geo(triangle vertexOutput IN[3], inout TriangleStream<geometryOutput> triStream)
{
    float3 pos = IN[0].vertex.xyz;

    float camDistance = length(ObjSpaceViewDir(IN[0].vertex));
    if (camDistance < _RenderDistance)
    {
        float smoothingMultiplier = camDistance < _RenderDistance - _RenderSmoothingDistance ? 1.0 :
            (1.0 - (camDistance - (_RenderDistance - _RenderSmoothingDistance)) / _RenderSmoothingDistance);

        float2 areasUV = (pos.xz + _GrassMap_ST.zw) / _GrassMap_ST.xy;
        float areasValue = tex2Dlod(_GrassMap, float4(areasUV, 0, 0)).r;
        if (areasValue > _GrassTreshold)
        {
            // Each blade of grass is constructed in tangent space with respect
            // to the emitting vertex's normal and tangent vectors, where the width
            // lies along the X axis and the height along Z.

            // Construct random rotations to point the blade in a direction.
            float3x3 facingRotationMatrix = AngleAxis3x3(rand(pos) * UNITY_TWO_PI, float3(0, 0, 1));
            // Matrix to bend the blade in the direction it's facing.
            float3x3 bendRotationMatrix = AngleAxis3x3(rand(pos.zzx) * _BendRotationRandom * UNITY_PI * 0.5, float3(-1, 0, 0));


            float3x3 windRotation;
            if (_WindStrength > 0)
            {
                // Sample the wind distortion map, and construct a normalized vector of its direction.
                float2 uv = pos.xz * _WindDistortionMap_ST.xy + _WindDistortionMap_ST.zw + _WindFrequency * _Time.y;
                float2 windSample = (tex2Dlod(_WindDistortionMap, float4(uv, 0, 0)).xy * 2 - 1) * _WindStrength;
                float3 wind = normalize(float3(windSample.xy, 0));

                windRotation = AngleAxis3x3(UNITY_PI * windSample, wind);
            }
            else windRotation = AngleAxis3x3(UNITY_PI * float2(0, 0), float3(0, 0, 0));


            // Construct a matrix to transform our blade from tangent space
            // to local space; this is the same process used when sampling normal maps.
            float3 vNormal = IN[0].normal;
            float4 vTangent = IN[0].tangent;
            float3 vBinormal = cross(vNormal, vTangent) * vTangent.w;

            float3x3 tangentToLocal = float3x3(
                vTangent.x, vBinormal.x, vNormal.x,
                vTangent.y, vBinormal.y, vNormal.y,
                vTangent.z, vBinormal.z, vNormal.z);

            // Construct full tangent to local matrix, including our rotations.
            // Construct a second matrix with only the facing rotation; this will be used 
            // for the root of the blade, to ensure it always faces the correct direction.
            float3x3 transformationMatrix = mul(mul(mul(tangentToLocal, windRotation), facingRotationMatrix), bendRotationMatrix);
            float3x3 transformationMatrixFacing = mul(tangentToLocal, facingRotationMatrix);

            float height = (rand(pos.zyx) * 2 - 1) * _BladeHeightRandom + _BladeHeight * smoothingMultiplier;
            float width = (rand(pos.xzy) * 2 - 1) * _BladeWidthRandom + _BladeWidth * smoothingMultiplier;
            float forward = rand(pos.yyz) * _BladeForward;

            for (int i = 0; i < BLADE_SEGMENTS; i++)
            {
                float t = i / (float)BLADE_SEGMENTS;

                float segmentHeight = height * t;
                float segmentWidth = width * (1 - t);
                float segmentForward = pow(t, _BladeCurve) * forward;

                // Select the facing-only transformation matrix for the root of the blade.
                float3x3 transformMatrix = i == 0 ? transformationMatrixFacing : transformationMatrix;

                triStream.Append(GenerateGrassVertex(pos, segmentWidth, segmentHeight, segmentForward, float2(0, t), transformMatrix));
                triStream.Append(GenerateGrassVertex(pos, -segmentWidth, segmentHeight, segmentForward, float2(1, t), transformMatrix));
            }

            // Add the final vertex as the tip.
            triStream.Append(GenerateGrassVertex(pos, 0, height, forward, float2(0.5, 1), transformationMatrix));
        }
    }
}
ENDCG

SubShader
{
    Cull Off

    Pass
    {
        Tags
        {
            "RenderType" = "Opaque"
            "LightMode" = "ForwardBase"
        }

        CGPROGRAM
        #pragma vertex vert
        #pragma geometry geo
        #pragma fragment frag

        #pragma hull hull
        #pragma domain domain

        #pragma target 4.6
        #pragma multi_compile_fwdbase
        
        //#include "Lighting.cginc"

        float4 _TopColor;
        float4 _BottomColor;
        float _TranslucentGain;

        float4 frag(geometryOutput i, fixed facing : VFACE) : SV_Target
        {
            float3 normal = facing > 0 ? i.normal : -i.normal;

            float shadow = SHADOW_ATTENUATION(i);
            float NdotL = saturate(saturate(dot(normal, _WorldSpaceLightPos0)) + _TranslucentGain) * shadow;

            float3 ambient = ShadeSH9(float4(normal, 1));
            float4 lightIntensity = float4(ambient, 1) + NdotL;// * _LightColor0;
            float4 col = lerp(_BottomColor, _TopColor * lightIntensity, i.uv.y);
            
            return col;
        }
        ENDCG
    }
}

Ответы

▲ -1

Доблестный ChatGPT подсказал, что кроме установки текстуры методом SetTexture нужно еще пользоваться SetTextureScale и SetTextureOffset, потому что размера текстуры записанного в самой текстуре не хватает.