- Home /
shader for light replacement blending, instead of additive blending?
So, I'm in a bit of a unique situation where I want my lights to "paint" the objects with the light color specified, with proper attenuation. Realistically though, when you specify a light color to a light source and shine it on said object, it does an additive blend per "ForwardAdd" pass with the "Blend One One" option specified, like how all the default shaders handle it.
For most cases, this is desired, but for my situation it isn't. I'm still learning a bit about how vertex fragment shaders work and I'm getting the jist of things but any tinkering with what I have does not get me closer to the results I want.
Here is a snippet of the shader in question. I've worked on top of the code found [here][1] and have learned a great deal from it.
Pass {
Tags { "LightMode" = "ForwardAdd" }
// pass for additional light sources
Blend One One // Additive
//BlendOp Max
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform float4 _LineColor; // define shader property for shaders
float _LineWidth;
float _LineWidthX;
// The following built-in uniforms (apart from _LightColor0)
// are defined in "UnityCG.cginc", which could be #included
//uniform float4 unity_Scale; // w = 1/scale; see _World2Object
// uniform float3 _WorldSpaceCameraPos;
// uniform float4x4 _Object2World; // model matrix
// uniform float4x4 _World2Object; // inverse model matrix
// (all but the bottom-right element have to be scaled
// with unity_Scale.w if scaling is important)
//uniform float4 _WorldSpaceLightPos0;
// position or direction of light source
uniform float4 _LightColor[4];
// color of light source (from "Lighting.cginc")
struct vertexInput {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
float3 normal : NORMAL;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 col : COLOR;
float2 uv : TEXCOORD0;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
float4x4 modelMatrix = _Object2World;
float4x4 modelMatrixInverse = _World2Object;
// multiplication with unity_Scale.w is unnecessary
// because we normalize transformed vectors
float3 normalDirection = normalize(float3(
mul(float4(input.normal, 0.0), modelMatrixInverse)));
float3 lightDirection;
float attenuation;
if (0.0 == _WorldSpaceLightPos0.w) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection =
normalize(float3(_WorldSpaceLightPos0));
}
else // point or spot light
{
float3 vertexToLightSource = float3(_WorldSpaceLightPos0
- mul(modelMatrix, input.vertex));
float distance = length(vertexToLightSource);
attenuation = 1.0 / distance; // linear attenuation
lightDirection = normalize(vertexToLightSource);
}
float3 diffuseReflection =
attenuation * float3(_LightColor[0]) * 4;
output.col = float4(diffuseReflection, 1.0);
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.uv = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
if (input.uv.x < _LineWidthX ||
input.uv.y < _LineWidth ||
input.uv.x > 1 - _LineWidthX ||
input.uv.y > 1 - _LineWidth)
{
return input.col;
}
else
{
return float4(0,0,0,0);
}
}
ENDCG
}
Is there a way to specify a certain color on a light source, even if it's darker than the object's current color, and basically paint with it, with the proper attenuation (so if I have a completely black light source and I put it on a blue surface, it will paint that surface black, but then fade as the "light" gets weaker)? I'm not sure if it has to do with the Blend type (I've tried various combinations unsuccessfully, but may have missed it) or with how I'm setting the color for my ForwardAdd pass.
Whether there is a solution or not, thanks in advance for the help! =) [1]: http://en.wikibooks.org/wiki/Cg_Programming/Unity/Diffuse_Reflection
Did you ever find an answer for this? I am in the same situation.
Your answer
Follow this Question
Related Questions
Lighting and lightmapping - OpenGL ES 1.1? 3 Answers
How to change type of shading? 1 Answer
Lighting breaks when zooming in 1 Answer
Vertex color blending shader 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers