Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411497 Posts in 69373 Topics- by 58428 Members - Latest Member: shelton786

April 25, 2024, 07:36:06 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Unity shaders: custom blending
Pages: [1]
Print
Author Topic: Unity shaders: custom blending  (Read 5895 times)
Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« on: November 04, 2014, 05:03:15 AM »

Hi, I was wondering if it's even possible to do more complicated blend functions in Unity.
From what I understand the 'Blend' command can only multiply Src and Dst by a single factor chosen from a somewhat limited list.
But what if I'd like to do a more complicated multiplication, for example:

Result = ((DstColor.r + DstColor.g + DstColor.b)/3) * SrcAlpha * Src + (1 - ((DstColor.r + DstColor.g + DstColor.b)/3) * SrcAlpha) * Dst

Is it possible to do that in the fragment shader somehow?
Logged

Columbo
Level 0
***


View Profile
« Reply #1 on: November 04, 2014, 12:36:03 PM »

I don't know much about Unity, but generally your options are much more limited than that when it comes to blending on current GPUs.

There are some exceptions if you can take advantage of OpenGL extensions on certain cards, or on some consoles, but the chances are that's not an option for you.

To do this sort of fancy blending, you really need to have your scene rendered out to a texture, then use said texture as an input. That way you can do whatever crazy maths you need to in an ordinary pixel shader.
Logged

Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #2 on: November 04, 2014, 01:43:05 PM »

I see, after a lot of googling it seems it's no different in Unity shaders, but thanks for the answer Smiley

In the end I managed to get a somewhat similar effect to what I wanted by combining the basic blending and pre-multiplying alpha. If anyone ever finds this topic, this is what works quite nice for me for blood splatters:

Code:
Blend DstColor OneMinusSrcAlpha
...
multiply pixel color by pixel alpha in the fragment shader
Logged

LuisAnton
Level 1
*


View Profile WWW
« Reply #3 on: November 20, 2014, 05:30:47 AM »

Silly question: I've been working with Unity since 2009, but never touched shaders. Is there a nice place to get a grasp of then?

edit: lol, I just found this post http://forums.tigsource.com/index.php?topic=44284.0
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #4 on: November 23, 2014, 02:40:26 PM »

Huh it's like you are using the fixed function pipeline, use full Cg shader for more complex blending
Logged

Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #5 on: November 24, 2014, 06:31:02 AM »

I'm not sure what you mean Gimym, I'm using Unity CG shaders.
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #6 on: November 24, 2014, 08:08:03 AM »

Well I think there is 3 convenient mode in unity shader, the fixed function pipeline have command like blend one one, the shaderlab mode who use surf function, and pure cg confine into pass and "CG bracket". Surface and CG can be arbitrarily complex.
Logged

Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #7 on: November 24, 2014, 08:26:09 AM »

The question is how can I blend source and destination colour in a CG shader other then using the Blend keyword.

Surface shaders have their own limitations and I wasn't for the life of me able to write one that would work with Unity projectors, and this is what I needed this for.
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #8 on: November 24, 2014, 08:45:04 AM »

I don't know how projector work, but that seems weird. Let me research that and I'm back.

What limitation surface shader have?
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #9 on: November 25, 2014, 03:17:15 AM »

That blending can be written

L = (DstColor.r + DstColor.g + DstColor.b)/3) * SrcAlpha

L * Src + (1 - L) * Dst

Here is more about projectors
http://en.wikibooks.org/wiki/Cg_Programming/Unity/Projectors


So my conclusion is that's not possible WITH blend, you have to use grabpass inside surface or pure CG code and that's a pro feature.

You can emulate it with multiple pass but then only for operation that haven't divergence, the way blend work is that you don't have really access to dest color, it just take the result of src and apply it to the color screen. It's an emulation of how old fixed function shader worked like with directx7.


http://docs.unity3d.com/Manual/SL-Blend.html
« Last Edit: November 25, 2014, 03:22:48 AM by Gimym JIMBERT » Logged

Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #10 on: November 25, 2014, 03:36:29 AM »

So my conclusion is that's not possible WITH blend, you have to use grabpass inside surface or pure CG code and that's a pro feature.

Yes, that's what Columbo pointed out earlier Smiley

You can emulate it with multiple pass but then only for operation that haven't divergence, the way blend work is that you don't have really access to dest color, it just take the result of src and apply it to the color screen. It's an emulation of how old fixed function shader worked like with directx7.

Not sure what you mean with multipass emulation and divergence, but I don't think I can get the result I want without access to dest, that's the whole problem.

Regarding projectors in Unity, I read that link and a lot of other resources, forums, articles etc. trying everything I could find and I was never able to get a surface shader to work with projectors. If I remember correctly the texture was always applied to the whole mesh I was projecting on, maybe I was missing something crucial, but I don't remember exactly what I tried, just that I came to the conclusion it's not possible.
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #11 on: November 25, 2014, 03:48:20 AM »

Basically each pass would be an operation, but that would be overkill. Also situation where you have s*d + s*l is not possible, you would need to compute s*d and s*l separately, store the result and add them together, which would not work in a chained pass (unless you rewrite it so that all operation can be applied in order). My English is failing me a bit but it's equivalent to parse operation to compute them.

For projector read the projector on unity docs, it says you need to have a clamp texture with an alpha border ... basically what it does is apply the shader to the whole mesh, but extend alpha which is not visible.
Logged

Netsu
Level 10
*****


proficient at just chillin'


View Profile WWW
« Reply #12 on: November 25, 2014, 03:51:26 AM »

Ah, yes, I could chain passes in this way, but like you say, it would only work if my expression could be written as a chain.

For projector read the projector on unity docs, it says you need to have a clamp texture with an alpha border ... basically what it does is apply the shader to the whole mesh, but extend alpha which is not visible.

It wasn't the clamping issue, the texture was applied using the UV mappings of the mesh it was projected upon, instead of using the projector matrix.
Logged

gimymblert
Level 10
*****


The archivest master, leader of all documents


View Profile
« Reply #13 on: November 25, 2014, 03:51:57 AM »

Quote
Note: When creating a projector, always be sure to set the wrap mode of the texture’s material of the projector to clamp. else the projector’s texture will be seen repeated and you will not achieve the desired effect of shadow over your character.
http://docs.unity3d.com/Manual/class-Projector.html

edit: was posting that while you answered Sad
Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic