Hi to community, I am working on a similar game like sims and I want to make wall textures with changing color capabilities.I am not using shader graphs cause I had some issues with batching so I desided to write my own shader. I am using below to pick colors via script Code (CSharp): var propBlock = new MaterialPropertyBlock(); this.gameObject.GetComponent<Renderer>().GetPropertyBlock(propBlock); // Assign our new value. _propBlock.SetColor("_Color", OrigColor); // Apply the edited values to the renderer. GetComponent<Renderer>().SetPropertyBlock(_propBlock); Let me explain what I need to achieve. In below picture I have a wall paint made in photoshop and I have made two textures : One for red , and one for white Code (CSharp): Shader "Custom/FloorBlock_settedProp" { Properties{ _Color("Color", Color) = (1,1,1,1) _ColorOverlay("ColorOverlay", Color) = (1,1,1,1) _MainTex("Albedo (RGB)", 2D) = "white" {} _SecondaryTex("Overlay Texture Color (RGB) Alpha (A)", 2D) = "white" {} [NoScaleOffset] _NormalMap("Normals", 2D) = "bump" {} _Glossiness("Smoothness", Range(0,1)) = 0.5 _Metallic("Metallic", Range(0,1)) = 0.0 } SubShader{ Tags { "RenderType" = "Opaque" } LOD 200 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard fullforwardshadows // Use Shader model 3.0 target #pragma target 3.0 sampler2D _MainTex; sampler2D _NormalMap; //additional sampler2D _SecondaryTex; struct Input { float2 uv_MainTex; //float2 uv_SecondTex; float2 uv_NormalMap; }; //additional //fixed4 _Color; half _Glossiness; half _Metallic; UNITY_INSTANCING_BUFFER_START(Props) UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color) UNITY_DEFINE_INSTANCED_PROP(fixed4, _ColorOverlay) UNITY_INSTANCING_BUFFER_END(Props) void surf(Input IN, inout SurfaceOutputStandard o) { //additional float4 mainTex = tex2D(_MainTex, IN.uv_MainTex); float4 overlayTex = tex2D(_SecondaryTex, IN.uv_MainTex); half3 mainTexVisible = mainTex.rgb * (1 - overlayTex.a); half3 overlayTexVisible = overlayTex.rgb * (overlayTex.a); //float3 finalColor = (mainTexVisible + overlayTexVisible) * _Color; //Main //fixed4 c = (tex2D(_MainTex, IN.uv_MainTex) * UNITY_ACCESS_INSTANCED_PROP(Props, _Color) + tex2D(_SecondaryTex, IN.uv_MainTex) * UNITY_ACCESS_INSTANCED_PROP(Props, _ColorOverlay)); //o.Albedo = c.rgb; fixed4 c = tex2D(_MainTex, IN.uv_MainTex); o.Albedo = lerp(UNITY_ACCESS_INSTANCED_PROP(Props, _Color), UNITY_ACCESS_INSTANCED_PROP(Props, _ColorOverlay), c.r); o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = c.a; o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_NormalMap)); } ENDCG } FallBack "Diffuse" }
Color_A5FB8792 != _Color ? Also you're just adding the two colored textures together. Presumably you want to lerp between them?
Thanks bgolus for the reply.I have tested lerp and it works! Color_A5FB8792 was wrong as I was trying to use shader graph and havent change it (edit original post). I made some adjustments to the shader code as well and changed texture to the one bellow(red and green) But I have another issue that I want your assist. Currently batching and color changing works great. If I want to change textures via script will the batch break (GPU Instancing)? Here is my material I want the user to be able to choose from collection of textures and use them to paint the wall ,with the textures of his choise and colors tha he will pick. Is that possible without breaking batch? Where should I store textures?
You cannot change textures and retain either batching or instancing (which is different than batching). With instancing you can changed instanced numerical properties (float, vector, or color), but you cannot change textures. If you want to support changing textures with instancing you have to use a Texture2dArray and have one of the instanced properties be the layer index. Batching is when Unity merges several meshes together into a single mesh either at build time / starting play mode (static batching) or at run time (dynamic batching). For those you cannot change the material properties at all. Not even with a material property block.
yes its still bit blur on my head as you can see! Ok I will leave batching out of equation for the moment as Instancing works great. So , regarding instancing! 1.you have to use a texture array : texture arrays will be on the shader itself or on other script?(yep just started with shaders) 2.instanced properties be the layer index : you are reffering to shader -> UNITY_DEFINE_INSTANCED_PROP etc? And what about layers? I only know the layers we use on inspector. Are others that are used for shaders?Keep in mind that wer are talking about more than 100 textures? Is possible to make material for each one and merge them on atlases..or something like that?
A texture array, or Texture2DArray, is a texture asset type. Basically it's a 3D texture where the z axis is treated as separate layers. If you're using 2020.2+ these can be imported from texture atlases. If you're using a Unity 2020.1 or older you have to create them with a custom script. After that they're just a texture asset you assign to the material, assuming your shader has a 2DArray property to accept it and you change the rest of the shader code to handle it properly. You can search around on your own to find examples.
Perfect bgolus!I would look into it this weekend and get back to discuss the results. thanks a lot for you assist
I have managed to make a shader with Texture2DRay,index and colors for each channel(R,G,B) as predefined props and change index of shader with script,using Material property ike bellow. GPU - Instance works as charm. I was thinking.. Is it better to have a shader with Texture2DRay and a script to pass index with the help of material properties(like above) or to have a Texture2DRay assigned to the script and pass texture to the shader with material property? The reason is, that I need to have 2xTexture2DRay(different dimmensions for each one) and I am thinking it may be easier to execute logic on script, than have shader with two Texture2DRay and decide inside shader which Texture2DRay to use. Any reccomendation ?