I have a material with its shader set to Skybox/Cubemap and I have cubemap1 assigned to the slot. Now I want to replace cubemap1 with cubemap2 and I found a script for this, but i can't seem to get it working.
any thoughts?
#pragma strict
var cubemap2 : Cubemap; //Change texture for cubemap
var shaderCubemap : Material; //Shader with cubemapslot
function Start () {
shaderCubemap.SetTexture("_Cube",cubemap2);
}
shaderCubemap.SetTexture("_Tex",cubemap2);
When you are not sure about a texture name in a shader, set it to debug in the top right corner of the inspector. It will display the shader and all its parameters with the naming actually used in it.
Related
I am trying to create a shader that would blend a background's texture with the 3d object's texture. The background texture is a render texture from another camera. I pass it to the shader of the foreground object.
The idea is to achieve an effect of various blendings on the 3d object "in the front".
The fragment shder looks like this:
fixed4 frag(v2f i) : SV_Target
{
float4 color_from_background = tex2D(_BackTex, float2(i.pos.x / _ScreenParams.x, i.pos.y / _ScreenParams.y)); //A
fixed4 surfcol = tex2D(_MainTex, i.uv);
fixed4 c = BlendMode_Multiply(color_from_background,fixed4(surfcol.rgb,surfcol.a * _Transparency));
return c;
}
It kind of works...
Unfortunately due to imprecisions in the division in the line marked with "//A" - I get visible artifacts along the object's edges. In this line I sample the background texture for the blending's input, How to solve that? First thing that comes to my mind is anti-aliasing. But I dont know how to implement it here. I tried to change sampling levels and filtering of the textures but it does not solve the problem.
I attach image that shows the problem. At the top part you can see the artifacts when using the shader. At the bottom the actual object with non-opaque material.
The solution to this is disabling the anti-aliasing in the project settings globally OR in the target render texture settings and camera settings. I only had it off in the target render texture which was not enough
I have a plane mesh (a custom trail) that uses an advanced shader in URP and I need it to detect overlaps and change it's color to red.
The application is 3d and the trail is always drawn at y zero. The user needs to have visual feedback when the trails overlap so they can fix their route.
I am trying to do it using a Stencil Shader but stencil for URP doesn't work like in built-in renderer.
This question has exactly what I need to do, but the shader doesn't work in URP. Whatever shader I try to do multiple passes of stencil it just renders the first pass and never detects the other passes.
In URP I was able to use stencil only with one writer shader and one reader shader and Replacing the stencil buffer (adding doesn't work).
Since it can't detect the two different passes I can't even do it using doubled objects with writer and readers and my reader having a pass for the advanced shader and one for the flat red color.
Remember, I need a bunch of plane trails to detect overlapping and self overlapping.
Can anyone make it work or suggest another approach? (I must finish this at my job)
Found two ways of doing it.
After some hours of searching I found this thread where Invertex says that:
URP doesn't automatically run all shader passes for performance reasons.
You could make a second material that has the other pass enabled and add it to the object's material list. It would effectively be the same.
So I made a Shader with:
Tags {
"RenderType" = "Opaque"
"Queue" = "Geometry-1"
}
Pass
{
Stencil {
Ref 0
Comp Equal
Pass IncrSat
Fail IncrSat
}
}
//here the code that renders when not overlapping
And another shader with:
//this one is in "Queue"="Geometry"
Stencil {
Ref 1
Comp Less
}
//here the code that renders when overlapping
Then I place both shaders in my prefab. Since it has only one submesh, it renders both materials in it.
The method above is an ugly and costly workaround, so I kept searching on the problem
The solution I was after was in this thread. We can use "LightMode" tags like "DepthOnly", "Meta", "SRPDefaultUnlit", "UniversalForward", etc... to bypass the passes in URP. They will render in a specific order, no matter in which order they are on your file. You are limited to a few but it solves it in my case.
Since "SRPDefaultUnlit" will render first for all objects and then "UniversalForward" will render for all objects, I can use this to my advantage.
Inside the first pass:
Tags
{
"LightMode" = "SRPDefaultUnlit"
}
Stencil
{
Ref 0
Comp Equal
Pass IncrSat
Fail IncrSat
}
//here the code that renders when not overlapping
Inside the second pass:
Tags
{
"LightMode" = "UniversalForward"
}
Stencil
{
Ref 1
Comp Less
}
//here the code that renders when overlapping
NOTE: If you're using the Built in Render the LightMode will not work, you'll have to use the default one and change the passes order in code to get the desired effect. You'll put the overlay one after the base pass.
This seem to be the final solution for me but feel free to contribute as you may help other people in the future.
I have material with Shader in unity.
How to get a value in code?
For example, i need change value EdgeWidth in code, how can i do it?
According to the Unity documentation, you need to find your material or your shader, in your script, and you have a lot of functions to change the value of a material, like .SetFloat().
Renderer rend = GetComponent<Renderer> ();
rend.material.SetFloat("EdgeWidth", -1.18f);
Here is my code:
root_level1.GetComponent<Renderer>().material.EnableKeyword ("_NORMALMAP");
Texture tex = Resources.Load("book-cover-1-glitched-23-11-2020-8-35-56-pm") as Texture;
root_level1.GetComponent<Renderer>().material.mainTexture = tex;
To change material texture in runtime you should change it by accessing shader properties. First of all you gonna check these properties in shader code or shader properties in unity inspector. If you want to check shader code, your goal is "properties" block:
Or you can select shader in Unity Editor and check Inspector Window:
So to change Base RGB Texture we should change property "_MainTex" and to change Color we have to change property "_Color".
I your example its gonna be like this:
root_level1.GetComponent<Renderer>().material.SetTexture("_MainTex", tex);
Okay so I have this code.
void Start () {
gameObject.GetComponent<Renderer> ().material.color = Color.green;
}
I expected my gameObject to change its color to green. I imported it as black and in the inspector it has turned to green however in the actual application it does not appear as green. I cant use gameObject.renderer.material.color = Color.green since unity tell me its basically outdated and that I have to use the new version. This is going to be really simple but what am I missing? Thanks in advance.
UPDATE: When I run the code a tab pops up in the inspector 'Sprites-Default (instance)' and if I change the selection box to Unlit > Color it works. Is there anyway of making this stick?
If you are trying to change a 2D sprite color try GetComponent<SpriteRenderer>().color = Color.green instead of just get "Renderer" component or try to setColor() with specular shader instead of direct attribution (you'll need a light source in scene).
the color changes but you cant see the result because the shader in your material needs light and you don't have lights so you will always see it black so you can add a light source or change the materials shader to unlight.
There are always two possibilities of not seeing the result of this code.
There's no light (a directional light or a point light) as pointed out by user2320445.
There is a light but you haven't imported the System.Collections namespace, i.e., your program misses the statement using System.Collections; in the beginning of the code. If you want to write the code without using the System.Collections namespace, then you can replace the line
gameObject.GetComponent<Renderer> ().material.color = Color.green;
with
gameObject.renderer.material.color = Color.green;
This does not require you to import the System.Collections namespace.