Jump to content

Space_Unicorn

Members
  • Posts

    31
  • Joined

  • Last visited

Posts posted by Space_Unicorn

  1. On 07/03/2020 at 16:58, andreisrww said:

    Я верю, что ты не можешь сделать это так просто. Попробуйте пройти по ссылке ниже. Создание внешнего веб-сервера для загрузки файлов может быть решением.

    Ссылка: Щелкните здесь

    Примерно это я сделал, только файлы загружаются не автоматически, а по запросу. Жаль что в МТА нет возможности просто отключить валидацию некоторых файлов.

  2. Сабж. Можно как-то отключить валидацию? Файлов очень много, из-за этого прогрузка у игроков может достигать 10-20 минут, в зависимости от ПК, естественно. При этом файлы эти юзаются не всегда, и было бы куда легче если бы валидация происходила только перед непосредственным использованием файла. Есть несколько мыслей по этому поводу, но все решения довольно костыльные и не очень красивые

  3. 15 hours ago, Kenix said:

    Я на своем опыте скажу, что это не так.
    Почему?
    Для маленьких модов да, можно в одном ресурсе, но дальше идут проблемы.
    Если проект будет большой и нужно в режиме реального времени обновлять его, например внести изменения в конфиг, то сделать не получится такое если всё в одном ресурсе. Нужно будет перезапускать весь мод.
    Также скорость разработки снизится, т.к сделав любое изменение вам придется долго ждать, особенно это касается верстки интерфейсов. Любое изменение в UI вы можете легко проверить в игре, сделав просто рестарт, остальные ресурсы будут работать как и работали.
    Лучше когда много ресурсов, каждый ресурс выполняется в своем VM, так безопаснее чем это всё делать в одной.
    Также если проект поделен по ресурсам есть другая проблема, это использование так называемых utility функций, их придется кидать в каждый ресурс, при грамотном подходе это решается легко.
    Если будете делать командой, то можно легко делать разработку, каждый работает над своим ресурсом и он легко внедряется на сервер.

    Организация ресурсов может быть такой:
    [assets] // папка с вашыми ресурсами, это могут быть шрифты, картинки, шейдеры, модели, звуки и т.д
    [ui] // UI вашего мода, например это может быть какой нибудь банк или автосалон
    [engine] // Ваш мод, основные компоненты, база или какие-то функции, utilities
    [third_party] // Ресурсы сторонних авторов
    [game] // Сами ресурсы реализация, например создание автосалонов на стороне сервера

    Также можно организовать папки по элементам
    [player]
    [vehicle] // например vehicle_tuning, vehicle_wheels.
    [property]
    и т.д

    Это тоже интересный подход.

    Есть в этом правда, но что-то внутри меня заставило отказаться от модульности, и я не пожалел. Отдельно у меня только тяжеловесные ресурсы -- звуки,карты и прочие ассеты, которые можно перезагрузить без прерывания игрового процесса

    А на счёт конфигов зависит от того насколько лень, можно ведь сделать конфиги которые будут в реалтайме обновляться из xml или json 

  4. Вообще, не совсем по теме, но: По своему опыту скажу - гораздо удобнее писать целый гейммод состоящий из одного ресурса, нежели разбивать его на части с кучей зависимостей и т.д
    Конечно, теряется возможность по-быстрому апдейтнуть какой либо модуль, но лично мне такая структура проекта кучу нервов сберегла

  5. 23 hours ago, K1parik said:

    почему?

     

    https://wiki.multitheftauto.com/wiki/TriggerClientEvent

    Note: To save client CPU, you should avoid setting sourceElement to the root element where possible. Using resourceRoot is usually sufficient if the event is handled by the same resource on the client.

     

    В твоем коде проблема в том что на клиенте эвент привязан к root (getRootElement()) а ты в качестве сурс элемента передаёшь игрока. 

    Fz68t3_95OI.jpg

    твой код заработает если source и getRootElement() заменишь на resourceRoot

  6. Не совсем понятно.
    Почему бы не использовать on(Client)ResourceStop и удалять все необходимые элементы? Возможно лезть в древо элементов впринципе не очень хорошая идея

    Не совсем понятно.
    Почему бы не использовать on(Client)ResourceStop и удалять все необходимые элементы? Возможно лезть в древо элементов впринципе не очень хорошая идея

     

    upd: в вики написано что элементы удаляются только тогда, когда останавливается ресурс который их создал

    https://wiki.multitheftauto.com/wiki/SetElementParent
    This function does not change when an element will be destroyed - Elements are always destroyed when the resource that created them is stopped

  7. Не советуется использовать  какой либо элемент (игрок, автомобиль, etc) при использовании триггера. Используйте всегда resourceRoot, а если нужен элемент (в данном случае игрок) передавайте его в качестве аргумента

  8.  

    https://wiki.multitheftauto.com/wiki/GetElementMatrix

    function getPositionFromElementOffset(element,offX,offY,offZ)
        local m = getElementMatrix ( element )  -- Get the matrix
        local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1]  -- Apply transform
        local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2]
        local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3]
        return x, y, z                               -- Return the transformed point
    end

     

    • Thanks 1
  9. Суть вопроса в названии топика. После отрисовки огромного кол-ва картинок в рендертаргет, функция сжирает до гигабайта видеопамяти, которую потом никак не освобождает. Картинки рисуются единожды, но даже спустя большое кол-во времени память не освобождается, вариант с DxTexture не актуален, т.к занимает куда больше времени, что очень критично в моей ситуации. Как быть? Это какой-то баг, или так и должно быть? 

  10. On 23.01.2018 at 14:38, Disinterpreter said:

    Да, достаточно Lua и SQL. Для некоторых очень индивидуальных решений может еще пригодиться HLSL

     

    Только для личного развития

    на счёт плюсов, можно ведь на нём кастомные модули писать, не?
     

  11. Сразу оговорюсь, что в шейдерах я не понимаю от слова совсем, и мне очень сложно понять их работу, ибо для меня всё это очень неочевидные моменты до которых я  не могу сам дойти.

    Итак, есть колеса, по умолчанию выглядят так:
     

    Spoiler

    NzvONpn4a2M.jpg

    (Обратите внимание: У колеса есть хром. Какой-никакой, но есть)
    С этими колесами мне нужно производить следующие манипуляции:
    1.Изменять ширину
    2.Изменять размер
    3.Изменять развал 

    Для всего этого у меня есть шейдер (не мой):
     

    Spoiler
    
    //
    // Example shader - ped_morph.fx
    //
    
    
    //---------------------------------------------------------------------
    // Ped morph settings
    //---------------------------------------------------------------------
    float3 sMorphSize = float3(0,0,0);
    float sCamber = 10;
    float sWidth = 0.2;
    float sRotationX = 0;
    float sRotationZ = 0;
    float3 sAxis = float3(0, 0, 0);
    float4 sColor = float4(1, 1, 1, 1);
    
    texture sReflectionTexture;
    
    float gFilmDepth = 0;
    float gFilmIntensity = 0.25;
    bool gFilmDepthEnable = false;
    
    
    //---------------------------------------------------------------------
    // Include some common stuff
    //---------------------------------------------------------------------
    #include "mta-helper.fx"
    
    sampler Sampler0 = sampler_state
    {
        Texture         = (gTexture0);
        MinFilter       = Linear;
        MagFilter       = Linear;
        MipFilter       = Linear;
    };
    
    samplerCUBE ReflectionSampler = sampler_state
    {
        Texture = (sReflectionTexture);
        MAGFILTER = LINEAR;
        MINFILTER = LINEAR;
        MIPFILTER = LINEAR;
        MIPMAPLODBIAS = 0.000000;
    };
    
    
    //---------------------------------------------------------------------
    // Structure of data sent to the vertex shader
    //---------------------------------------------------------------------
    struct VSInput
    {
        float3 Position : POSITION0;
        float3 Normal : NORMAL0;
        float4 Diffuse : COLOR0;
        float2 TexCoord : TEXCOORD0;
    };
    
    //---------------------------------------------------------------------
    // Structure of data sent to the pixel shader ( from the vertex shader )
    //---------------------------------------------------------------------
    struct PSInput
    {
        float4 Position : POSITION0;
        float4 Diffuse : COLOR0;
        float2 TexCoord : TEXCOORD0;
        float3 Tangent : TEXCOORD1;
        float3 Binormal : TEXCOORD2;
        float3 Normal : TEXCOORD3;
        float3 NormalSurf : TEXCOORD4;
        float3 View : TEXCOORD5;
        float4 BottomColor : TEXCOORD6;
        float3 SparkleTex : TEXCOORD7;
        float4 Diffuse2 : COLOR1;
    };
    
    
    //////////////////////////////////////////////////////////////////////////
    // Function to Index this texture - use in vertex or pixel shaders ///////
    //////////////////////////////////////////////////////////////////////////
    
    float calc_view_depth(float NDotV,float Thickness)
    {
        return (Thickness / NDotV);
    }
    
    
    float4 quat_from_axis_angle(float3 axis, float angle)
    {
        float4 qr;
        float half_angle = (angle * 0.5) * 3.14159 / 180.0;
        qr.x = axis.x * sin(half_angle);
        qr.y = axis.y * sin(half_angle);
        qr.z = axis.z * sin(half_angle);
        qr.w = cos(half_angle);
        return qr;
    }
    
    float4 quat_conj(float4 q)
    {
        return float4(-q.x, -q.y, -q.z, q.w);
    }
    
    float4 quat_mult(float4 q1, float4 q2)
    {
      float4 qr;
      qr.x = (q1.w * q2.x) + (q1.x * q2.w) + (q1.y * q2.z) - (q1.z * q2.y);
      qr.y = (q1.w * q2.y) - (q1.x * q2.z) + (q1.y * q2.w) + (q1.z * q2.x);
      qr.z = (q1.w * q2.z) + (q1.x * q2.y) - (q1.y * q2.x) + (q1.z * q2.w);
      qr.w = (q1.w * q2.w) - (q1.x * q2.x) - (q1.y * q2.y) - (q1.z * q2.z);
      return qr;
    }
    
    float3 rotate_vertex_position(float3 position, float3 axis, float angle)
    {
      float4 qr = quat_from_axis_angle(axis, angle);
      float4 qr_conj = quat_conj(qr);
      float4 q_pos = float4(position.x, position.y, position.z, 0);
    
      float4 q_tmp = quat_mult(qr, q_pos);
      qr = quat_mult(q_tmp, qr_conj);
    
      return float3(qr.x, qr.y, qr.z);
    }
    
    //------------------------------------------------------------------------------------------
    // VertexShaderFunction
    //  1. Read from VS structure
    //  2. Process
    //  3. Write to PS structure
    //------------------------------------------------------------------------------------------
    
    PSInput VertexShaderFunction(VSInput VS)
    {
        PSInput PS = (PSInput)0;
    
        PS.Position = mul(float4(VS.Position, 1), gWorldViewProjection);
    
        VS.Position *= float3(1 + sWidth, 1, 1);
    
        VS.Position = rotate_vertex_position(VS.Position, float3(1, 0, 0), float3(sRotationX, 0, 0));
        VS.Position = rotate_vertex_position(VS.Position, float3(0, 1, 0), float3(sCamber, 0, 0));
        VS.Position = rotate_vertex_position(VS.Position, float3(0, 0, 1), float3(sRotationZ, 0, 0));
        // Рассчитать позицию вершины на экране
        PS.Position = MTACalcScreenPosition(VS.Position);
    
        // Передать tex coords
        PS.TexCoord = VS.TexCoord;
    
        VS.Normal = rotate_vertex_position(VS.Normal, float3(1, 0, 0), float3(sRotationX, 0, 0));
        VS.Normal = rotate_vertex_position(VS.Normal, float3(0, 1, 0), float3(sCamber, 0, 0));
        VS.Normal = rotate_vertex_position(VS.Normal, float3(0, 0, 1), float3(sRotationZ, 0, 0));
        float3 worldNormal = mul(VS.Normal, (float3x3)gWorld);
    
        // ------------------------------- PAINT ----------------------------------------
    
        float3 worldPosition = MTACalcWorldPosition( VS.Position );
        PS.View = normalize(gCameraPosition - worldPosition);
    
        // Fake tangent and binormal
        float3 Tangent = VS.Normal.yxz;
        Tangent.xz = VS.TexCoord.xy;
        float3 Binormal = normalize( cross(Tangent, VS.Normal) );
        Tangent = normalize( cross(Binormal, VS.Normal) );
    
        // Transfer some stuff
        PS.TexCoord = VS.TexCoord;
        PS.Tangent = normalize(mul(Tangent, gWorldInverseTranspose).xyz);
        PS.Binormal = normalize(mul(Binormal, gWorldInverseTranspose).xyz);
        PS.Normal = normalize( mul(VS.Normal, (float3x3)gWorld) );
        PS.NormalSurf = VS.Normal;
    
        PS.SparkleTex.x = fmod( VS.Position.x, 10 ) * 4.0;
        PS.SparkleTex.y = fmod( VS.Position.y, 10 ) * 4.0;
        PS.SparkleTex.z = fmod( VS.Position.z, 10 ) * 4.0;
    
        PS.Diffuse = MTACalcGTABuildingDiffuse(VS.Diffuse) + float4(0.2, 0.2, 0.2, 0);
        return PS;
    }
    
    float4 PixelShaderFunction(PSInput PS) : COLOR0
    {
        float4 OutColor = 1;
    
        float4 paintColor = sColor;
        float4 maptex = tex2D(Sampler0,PS.TexCoord.xy);
        float4 delta = maptex - float4(0, 0, 0, 1);
        if (dot(delta,delta) < 0.2) {
            float4 Color = maptex * PS.Diffuse * 1;
            Color.a = PS.Diffuse.a;
            return Color;
        }
        // Some settings for something or another
        float microflakePerturbation = 1.00;
        float normalPerturbation = 1.00;
        float microflakePerturbationA = 0.10;
    
        // Compute paint colors
        float4 base = gMaterialAmbient;
    
        // Get the surface normal
        float3 vNormal = PS.Normal;
    
        // Micro-flakes normal map is a high frequency normalized
        // vector noise map which is repeated across the surface.
        // Fetching the value from it for each pixel allows us to
        // compute perturbed normal for the surface to simulate
        // appearance of micro-flakes suspended in the coat of paint:
    
        // This shader simulates two layers of micro-flakes suspended in
        // the coat of paint. To compute the surface normal for the first layer,
        // the following formula is used:
        // Np1 = ( a * Np + b * N ) / || a * Np + b * N || where a << b
        //
        float3 vNp1 = normalPerturbation * vNormal ;
    
        // To compute the surface normal for the second layer of micro-flakes, which
        // is shifted with respect to the first layer of micro-flakes, we use this formula:
        // Np2 = ( c * Np + d * N ) / || c * Np + d * N || where c == d
        float3 vNp2 = vNormal;
    
        // The view vector (which is currently in world space) needs to be normalized.
        // This vector is normalized in the pixel shader to ensure higher precision of
        // the resulting view vector. For this highly detailed visual effect normalizing
        // the view vector in the vertex shader and simply interpolating it is insufficient
        // and produces artifacts.
        float3 vView = normalize( PS.View );
    
        // Transform the surface normal into world space (in order to compute reflection
        // vector to perform environment map look-up):
        float3x3 mTangentToWorld = transpose( float3x3( PS.Tangent, PS.Binormal, PS.Normal ) );
        float3 vNormalWorld = normalize( mul( mTangentToWorld, vNormal ));
    
        // Compute reflection vector resulted from the clear coat of paint on the metallic
        // surface:
        float fNdotV = saturate(dot( vNormalWorld, vView));
    
        // Count reflection vector
        float3 vReflection = reflect(PS.View,PS.Normal);
    
        // Hack in some bumpyness
        vReflection.x+= vNp2.x * 0.1;
        vReflection.y+= vNp2.y * 0.1;
        // Sample environment map using this reflection vector:
        float4 envMap = texCUBE( ReflectionSampler, -vReflection.xzy );
        // Premultiply by alpha:
    
        envMap.rgb = envMap.rgb * envMap.rgb * envMap.rgb;
        // Brighten the environment map sampling result:
        envMap.rgb *= 0.8;
        envMap.rgb += PS.BottomColor.rgb;
        // Sample dust texture:
    
        // Combine result of environment map reflection with the paint color:
        float fEnvContribution = 1.0 - 0.5 * fNdotV;
    
        float4 finalColor = envMap * fEnvContribution + base * 0.1;
        finalColor.rgb += PS.Diffuse2.rgb  * 0.75;
        finalColor.a = 1.0;
        // Bodge in the car colors
        float4 Color = 0.15 + finalColor / 1 * 0.33 + PS.Diffuse * 0.9;
        //Color.rgb += finalColor * PS.Diffuse;
    
        Color *= maptex * paintColor;
        Color.a = PS.Diffuse.a;
        return Color;
    }
    
    
    //------------------------------------------------------------------------------------------
    // Techniques
    //------------------------------------------------------------------------------------------
    technique tec0
    {
        pass P0
        {
            VertexShader = compile vs_2_0 VertexShaderFunction();
            PixelShader  = compile ps_2_0 PixelShaderFunction();
        }
    }
    
    // Fallback
    technique fallback
    {
        pass P0
        {
            // Just draw normally
        }
    }

     

    После "прогонки" колёс через этот шейдер на выходе получается это:
     

    Spoiler

    chUb-LMigMA.jpg

    Колёса могут в развал, ширину, смену цвета дисков, но главное -- не смотря на то что в шейдере вроде как считается этот самый хром, по факту его нет (для него как я понял используется эта текстурка 3YxWq8kpF8c.jpg (создать в скрипте и "загрузить" её в шейдер я не забыл)


    То-же самое случается когда колесо просто-напросто красится пиксельным шейдером, но если создать renderTarget, и скормить ему шейдеру заменяющему текстуру, то колесо покрасится, и при этом хром который есть на диске по стандарту никуда не улетучивается:
     

    Spoiler

     

    
    float4 GetColor()
    {
        return float4( 0.2, 0.2, 0.2, 0.2);
    }
    
    
    texture tex0;
         
    technique simple {
        pass P0 {
        	texture[0] = tex0;
            MaterialAmbient = GetColor();
            MaterialDiffuse = GetColor();
            MaterialEmissive = GetColor();
            MaterialSpecular = GetColor();
        }
    }

    Результат:
    AZxlDbkyUW0.jpg

    Хром есть, цвет есть, значит нужно удалить из первой версии пиксельный шейдер, и оставить ему как задачу только лишь менять ширину/развал, а красить будем другим шейдером с помощью текстуры/рендертаргета:
     

    Spoiler
    
    //
    // Example shader - ped_morph.fx
    //
    
    texture wheelTexture;
    
    //---------------------------------------------------------------------
    // Ped morph settings
    //---------------------------------------------------------------------
    float3 sMorphSize = float3(0,0,0);
    float sCamber = 10;
    float sWidth = 0.2;
    float sRotationX = 0;
    float sRotationZ = 0;
    float3 sAxis = float3(0, 0, 0);
    
    texture sReflectionTexture;
    
    float gFilmDepth = 0;
    float gFilmIntensity = 0.25;
    bool gFilmDepthEnable = false;
    
    
    //---------------------------------------------------------------------
    // Include some common stuff
    //---------------------------------------------------------------------
    #include "mta-helper.fx"
    
    sampler Sampler0 = sampler_state
    {
        Texture         = (gTexture0);
        MinFilter       = Linear;
        MagFilter       = Linear;
        MipFilter       = Linear;
    };
    
    samplerCUBE ReflectionSampler = sampler_state
    {
        Texture = (sReflectionTexture);
        MAGFILTER = LINEAR;
        MINFILTER = LINEAR;
        MIPFILTER = LINEAR;
        MIPMAPLODBIAS = 0.000000;
    };
    
    
    //---------------------------------------------------------------------
    // Structure of data sent to the vertex shader
    //---------------------------------------------------------------------
    struct VSInput
    {
        float3 Position : POSITION0;
        float3 Normal : NORMAL0;
        float4 Diffuse : COLOR0;
        float2 TexCoord : TEXCOORD0;
    };
    
    //---------------------------------------------------------------------
    // Structure of data sent to the pixel shader ( from the vertex shader )
    //---------------------------------------------------------------------
    struct PSInput
    {
        float4 Position : POSITION0;
        float4 Diffuse : COLOR0;
        float2 TexCoord : TEXCOORD0;
        float3 Tangent : TEXCOORD1;
        float3 Binormal : TEXCOORD2;
        float3 Normal : TEXCOORD3;
        float3 NormalSurf : TEXCOORD4;
        float3 View : TEXCOORD5;
        float4 BottomColor : TEXCOORD6;
        float3 SparkleTex : TEXCOORD7;
        float4 Diffuse2 : COLOR1;
    };
    
    
    //////////////////////////////////////////////////////////////////////////
    // Function to Index this texture - use in vertex or pixel shaders ///////
    //////////////////////////////////////////////////////////////////////////
    
    float calc_view_depth(float NDotV,float Thickness)
    {
        return (Thickness / NDotV);
    }
    
    
    float4 quat_from_axis_angle(float3 axis, float angle)
    {
        float4 qr;
        float half_angle = (angle * 0.5) * 3.14159 / 180.0;
        qr.x = axis.x * sin(half_angle);
        qr.y = axis.y * sin(half_angle);
        qr.z = axis.z * sin(half_angle);
        qr.w = cos(half_angle);
        return qr;
    }
    
    float4 quat_conj(float4 q)
    {
        return float4(-q.x, -q.y, -q.z, q.w);
    }
    
    float4 quat_mult(float4 q1, float4 q2)
    {
      float4 qr;
      qr.x = (q1.w * q2.x) + (q1.x * q2.w) + (q1.y * q2.z) - (q1.z * q2.y);
      qr.y = (q1.w * q2.y) - (q1.x * q2.z) + (q1.y * q2.w) + (q1.z * q2.x);
      qr.z = (q1.w * q2.z) + (q1.x * q2.y) - (q1.y * q2.x) + (q1.z * q2.w);
      qr.w = (q1.w * q2.w) - (q1.x * q2.x) - (q1.y * q2.y) - (q1.z * q2.z);
      return qr;
    }
    
    float3 rotate_vertex_position(float3 position, float3 axis, float angle)
    {
      float4 qr = quat_from_axis_angle(axis, angle);
      float4 qr_conj = quat_conj(qr);
      float4 q_pos = float4(position.x, position.y, position.z, 0);
    
      float4 q_tmp = quat_mult(qr, q_pos);
      qr = quat_mult(q_tmp, qr_conj);
    
      return float3(qr.x, qr.y, qr.z);
    }
    
    //------------------------------------------------------------------------------------------
    // VertexShaderFunction
    //  1. Read from VS structure
    //  2. Process
    //  3. Write to PS structure
    //------------------------------------------------------------------------------------------
    
    PSInput VertexShaderFunction(VSInput VS)
    {
        PSInput PS = (PSInput)0;
    
        PS.Position = mul(float4(VS.Position, 1), gWorldViewProjection);
    
        VS.Position *= float3(1 + sWidth, 1, 1);
    
        VS.Position = rotate_vertex_position(VS.Position, float3(1, 0, 0), float3(sRotationX, 0, 0));
        VS.Position = rotate_vertex_position(VS.Position, float3(0, 1, 0), float3(sCamber, 0, 0));
        VS.Position = rotate_vertex_position(VS.Position, float3(0, 0, 1), float3(sRotationZ, 0, 0));
        // Рассчитать позицию вершины на экране
        PS.Position = MTACalcScreenPosition(VS.Position);
    
        // Передать tex coords
        PS.TexCoord = VS.TexCoord;
    
        VS.Normal = rotate_vertex_position(VS.Normal, float3(1, 0, 0), float3(sRotationX, 0, 0));
        VS.Normal = rotate_vertex_position(VS.Normal, float3(0, 1, 0), float3(sCamber, 0, 0));
        VS.Normal = rotate_vertex_position(VS.Normal, float3(0, 0, 1), float3(sRotationZ, 0, 0));
        float3 worldNormal = mul(VS.Normal, (float3x3)gWorld);
    
        // ------------------------------- PAINT ----------------------------------------
    
        float3 worldPosition = MTACalcWorldPosition( VS.Position );
        PS.View = normalize(gCameraPosition - worldPosition);
    
        // Fake tangent and binormal
        float3 Tangent = VS.Normal.yxz;
        Tangent.xz = VS.TexCoord.xy;
        float3 Binormal = normalize( cross(Tangent, VS.Normal) );
        Tangent = normalize( cross(Binormal, VS.Normal) );
    
        // Transfer some stuff
        PS.TexCoord = VS.TexCoord;
        PS.Tangent = normalize(mul(Tangent, gWorldInverseTranspose).xyz);
        PS.Binormal = normalize(mul(Binormal, gWorldInverseTranspose).xyz);
        PS.Normal = normalize( mul(VS.Normal, (float3x3)gWorld) );
        PS.NormalSurf = VS.Normal;
    
        PS.SparkleTex.x = fmod( VS.Position.x, 10 ) * 4.0;
        PS.SparkleTex.y = fmod( VS.Position.y, 10 ) * 4.0;
        PS.SparkleTex.z = fmod( VS.Position.z, 10 ) * 4.0;
    
        PS.Diffuse = MTACalcGTABuildingDiffuse(VS.Diffuse) + float4(0.2, 0.2, 0.2, 0);
        return PS;
    }
    
    //------------------------------------------------------------------------------------------
    // Techniques
    //------------------------------------------------------------------------------------------
    technique tec0
    {
        pass P0
        {
            VertexShader = compile vs_2_0 VertexShaderFunction();
        }
    }
    
    // Fallback
    technique fallback
    {
        pass P0
        {
            // Just draw normally
        }
    }

    "Новая" версия шейдера развала/ширины без пиксельной покраски

    Накладываем "новый" шейдер для ширины и развала, + накладываем шейдер на покраску через замену текстуры, результат:
     

    Spoiler

    ZEfYUDl_apY.jpgrfqi1NWpTu8.jpg

     

     

    Итак, вопросы:
    1.Если можно, то как подружить эти два шейдера

    2.Если можно, то как заменять только ОДНУ текстуру через "длинный" шейдер до того как вертексный шейдер её "растянет"

    (при этом этот шейдер применяется на все текстуры на обьекте)

    shader\applyToWorldTexture("*", object)

    3.Если можно, то как починить хром в первой версии шейдера, который красит диск с помощью пиксельного шейдера (я кстати так и не смог понять почему он красит только диск, ведь накладывается шейдер на все текстурки) 

    наверное, это условие:

    if (dot(delta,delta) < 0.2) {
            float4 Color = maptex * PS.Diffuse * 1;
            Color.a = PS.Diffuse.a;
            return Color;
        }

     

     

    p.s. Я шерстил по майкрософтовским докам, честно скажу: Не осилил и не понял

    Спасибо за внимание, надеюсь на вашу помощь.

    p.s. Если задача сложная, или большой обьём, то могу материально отблагодарить за работу

  12. Здравствуйте, необходимо сделать отрисовку картинок на стёкле автомобиля, при этом картинка не должна быть прозрачной, а стекло должно.

    Изначально шейдер выглядел так: 

    texture gTexture;
    
    technique TexReplace
    {
        pass P0
        {
            Texture[0] = gTexture;
        }
    }

    Результат был таким:

    Spoiler

    yEn2bpKYFT8.jpg


    После этого я сделал текстуру стекла непрозрачной, и попытался давать ей прозрачность шейдером и также отрисовывать картинки:

    float alpha = 0.5;
      
    struct PSInput 
    { 
        float4 Diffuse      : COLOR0; 
    }; 
      
    float4 PixelShaderFunction( PSInput PS ) : COLOR0 
    { 
        float4 color = PS.Diffuse; 
        
        color.a = alpha; 
        
        return color; 
    } 
      
    
    texture gTexture;
    
    technique TexReplace
    {
        pass P0
        {
            AlphaBlendEnable    = TRUE; 
            DestBlend           = INVSRCALPHA; 
            SrcBlend            = SRCALPHA; 
             
            PixelShader         = compile ps_2_0 PixelShaderFunction(); 
    
            Texture[0] = gTexture;
        }
    }


    В результате стекло становилось прозрачным, но картинки вообще не отображались.

     

    В HLSL не разбираюсь вообще, и даже далеко нет полного понимания того как работают шейдеры впринципе. Поэтому обращаюсь сюда

    Как можно всё-таки отрисовывать картинки на стекле так, чтобы они не были прозрачны? 

  13. 11 hours ago, Disinterpreter said:

    Если хотите сделать лучше сообщество, попробуйте сделать это сами, вы можете создать тему, где будете делать обзоры на сервера. И оценивать их по нескольким критериям.

    зачем что-то делать, если можно просто ныть на форуме? Диву даюсь

  14. UPD:
    Проблема решена
    проблема была в функции restoreModel 
    (Я позволяю игрокам выгружать/загружать модели чтобы они могли освобождать память в ущерб текстуркам)

    Суть решения:
    Вместо engineRestoreModel()
    использую destroyElement() (Удаляю загруженную engineLoad'oм дффку/тхдшку)

     

    И, кстати, видимо этот баг появляется только когда даешь engineLoad'у raw-data, ибо когда я просто грузил модели методом engineLoad('file.txd') то утечки никакой не было, из чего и решил что проблема в string.sub/fileOpen

    • Like 1
×
×
  • Create New...