- Home /
How to add emission to Unity custom shader?
I use the following shader in Unity. Ring like sonar is spreading from the place where game objects collided. I would like to add emission to make this ring visible even in the dark.I attach this shader to the wall and the floor, but I want to add emission to the ring that appears when the player hits the wall or the floor, not the wall and the floor itself.
The setting for making it dark is as follows.
Set the Intensity Multiplier ofEnvironment Lightning to 0.
Remove skybox.
Set the Background of Camera to black.
The shader I use is below.
Shader "MadeByProfessorOakie/SimpleSonarShader" {
Properties{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
_RingColor("Ring Color", Color) = (1,1,1,1)
_RingColorIntensity("Ring Color Intensity", float) = 2
_RingSpeed("Ring Speed", float) = 1
_RingWidth("Ring Width", float) = 0.1
_RingIntensityScale("Ring Range", float) = 1
_RingTex("Ring Texture", 2D) = "white" {}
}
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, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
sampler2D _RingTex;
struct Input {
float2 uv_MainTex;
float3 worldPos;
float3 uv_Illum;
};
// The size of these arrays is the number of rings that can be rendered at once.
// If you want to change this, you must also change QueueSize in SimpleSonarShader_Parent.cs
half4 _hitPts[20];
half _StartTime;
half _Intensity[20];
half _Glossiness;
half _Metallic;
fixed4 _Color;
fixed4 _RingColor;
// 追加
fixed4 _EmissionLM;
half _RingColorIntensity;
half _RingSpeed;
half _RingWidth;
half _RingIntensityScale;
void surf(Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
half DiffFromRingCol = abs(o.Albedo.r - _RingColor.r) + abs(o.Albedo.b - _RingColor.b) + abs(o.Albedo.g - _RingColor.g);
// Check every point in the array
// The goal is to set RGB to highest possible values based on current sonar rings
for (int i = 0; i < 20; i++) {
half d = distance(_hitPts[i], IN.worldPos);
half intensity = _Intensity[i] * _RingIntensityScale;
half val = (1 - (d / intensity));
if (d < (_Time.y - _hitPts[i].w) * _RingSpeed && d >(_Time.y - _hitPts[i].w) * _RingSpeed - _RingWidth && val > 0) {
half posInRing = (d - ((_Time.y - _hitPts[i].w) * _RingSpeed - _RingWidth)) / _RingWidth;
// Calculate predicted RGB values sampling the texture radially
float angle = acos(dot(normalize(IN.worldPos - _hitPts[i]), float3(1,0,0)));
val *= tex2D(_RingTex, half2(1 - posInRing, angle));
half3 tmp = _RingColor * val + c * (1 - val);
// Determine if predicted values will be closer to the Ring color
half tempDiffFromRingCol = abs(tmp.r - _RingColor.r) + abs(tmp.b - _RingColor.b) + abs(tmp.g - _RingColor.g);
if (tempDiffFromRingCol < DiffFromRingCol)
{
// Update values using our predicted ones.
DiffFromRingCol = tempDiffFromRingCol;
o.Albedo.r = tmp.r;
o.Albedo.g = tmp.g;
o.Albedo.b = tmp.b;
o.Albedo.rgb *= _RingColorIntensity;
}
}
}
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
}
ENDCG
}
FallBack "Diffuse"
}
Answer by Pangamini · Feb 12, 2018 at 11:58 PM
All you need is to output the emission color to o.Emission
Btw instead of writing o.Albedo.r = tmp.r; o.Albedo.g = tmp.g; o.Albedo.b = tmp.b;
You can just write o.Albedo.rgb = tmp;
@Panga$$anonymous$$i I rewrote it exactly as you taught, and it worked. I rewrote shader as follows.
// Deter$$anonymous$$e if predicted values will be closer to the Ring color
half tempDiffFromRingCol = abs(tmp.r - _RingColor.r) + abs(tmp.b - _RingColor.b) + abs(tmp.g - _RingColor.g);
if (tempDiffFromRingCol < DiffFromRingCol)
{
// Update values using our predicted ones.
//DiffFromRingCol = tempDiffFromRingCol;
/*
o.Albedo.r = tmp.r;
o.Albedo.g = tmp.g;
o.Albedo.b = tmp.b;
o.Albedo.rgb *= _RingColorIntensity;
*/
// Change
o.Emission.r = tmp.r;
o.Emission.g = tmp.g;
o.Emission.b = tmp.b;
o.Albedo.rgb = tmp;
}
That was a really big help! Thank you very much!
That's good to hear. But same for o.Emission, you can just write o.Emission = tmp;
(since both are vectors of 3 values)
I rewrote the code. I am a beginner of shader writing, so your answer was very helpful.Thank you for $$anonymous$$ching me in detail!
Your answer
![](https://koobas.hobune.stream/wayback/20220612152515im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Modifying properties of the Standard shader 1 Answer
How to get emission map to tile along SpeedTree? 0 Answers
Custom (Sprite-)Shader: Combine Sprite with light and original Sprite 0 Answers
Change linerenderer color to custom shader's color 1 Answer
Change emission brigthness in standard shader with script 1 Answer