Animating materials

Hi,
Let’s say i have 2 materials referencing the same shader effect :

<material id=“blue”>
<instance_effect url=#phong>
<setparam ref=“diffuse”>
<float3>0 0 1</float3>
</setparam>
</instance_effect>
</material>

<material id=“red”>
<instance_effect url=#phong>
<setparam ref=“diffuse”>
<float3>1 0 0</float3>
</setparam>
</instance_effect>
</material>

Now, let’s suppose i want to animate the diffuse parameter but only for material “blue”.
If the output of the animation channel is connected to the diffuse <newparam> sid of phong <effect>, then both materials will be animated which is not what i want.

I am forced to duplicate the <effect> definition, just because Collada specification does not allow a channel’s output to target <material><instance_effect><setparam> node directly.

Is there another solution that would avoid duplicating the <effect> definition ?

Thanks

Then target with an sid_ref anchored at id “blue”.

Not quite. COLLADA materials are represented as an instantiation of an effect so it describes a connection to an instance of your “phong” effect. COLLADA does not dictate policy for instantiation and your application can do what it needs to do.

A <channel> target is an SID reference so it can target anything in the same document that has an ID and/or SID that you can use to construct a unique path. For example:


<material id="blue">
  <instance_effect sid="blue_effect" url=#phong>
    <setparam ref="diffuse">
      <float3>0 0 1</float3>
    </setparam>
  </instance_effect>
</material>

<animation>
  ...
  <sampler id="diffuse_sampler" />
  <channel source="#diffuse_sampler" target="blue/blue_effect/diffuse" />
</animation>

Are you sure “blue/blue_effect/diffuse” is a valid SID ?
<setparam> does not have any SID. So how can you target anything in this node ?

Ah good catch. I mistook “ref” for “sid”. For that approach you would have to use an <extra> to provide the necessary SID reference in that scope.

I think adding a <param> to your <bind_material> is the better approach for what you want to do.

Is it better to put the name of the effect parameter to animate in the sid or name attribute of <param> ?

<instance_geometry>
    <bind_material>
        <param sid="diffuse" type="float4"/>
    </bind_material>
    ...
</instance_geometry>

or

<instance_geometry>
    <bind_material>
        <param sid="here" name="diffuse" type="float4"/>
    </bind_material>
    ...
</instance_geometry>

The name attribute is just user data. You want to use the semantic attribute:


<instance_geometry>
    <bind_material>
        <param sid="animated_diffuse" semantic="diffuse" type="float4" />
    </bind_material>
    ...
</instance_geometry>

You application will bind the param to the effect/shader diffuse using the semantic value such that animating the param will change the diffuse color values in that instance of the effect/shader.

See COLLADA 1.5 spec and Chapter 8: FX Reference, bind_material for more details.

Mark,
If semantic is supposed to reference a parameter, then why isn’t it of the same type as the attribute ref of <setparam> ?
The type for <setparam> ref attribute is xs:token
The type for <param> semantic attribute is xs:NMTOKEN

If the effect parameter is an <array> of values, how do you target an individual value ?
Does it follow the same array-indexing syntax as for <setparam> ?

For instance :


<effect>
    <newparam sid="numbers">
        <array length="4">
            <float>1.0</float>
            <float>2.0</float>
            <float>3.0</float>
            <float>4.0</float>
        </array>
    </newparam>
</effect>

<instance_geometry>
    <bind_material>
        <param sid="animated_value" semantic="numbers[2]" type="float"/>
    </bind_material>
</instance_geometry>

Thanks for your help 8)

I have just realized that <param> cannot reference a material parameter directly because <bind_material> may contain several <instance_material> nodes. In the following example, <param> does not know if “diffuse” belongs to mat1 or mat2 :


<instance_geometry url="#BeechTree">
    <bind_material>
        <param sid="here" semantic="diffuse" type="float4"/>
        <technique_common>
            <instance_material symbol="mat1" target="mat1"/>
            <instance_material symbol="mat2" target="mat2"/>
        </technique_common>
    </bind_material>
</instance_geometry>

So i guess i should use nodes to connect nodes to material parameters :


<instance_geometry url="#BeechTree">
    <bind_material>
        <param sid="here" type="float4"/>
        <technique_common>
            <instance_material symbol="mat1" target="mat1"/>
            <instance_material symbol="mat2" target="mat2">
                <bind semantic="diffuse" target="here"/>
            </instance_material>
        </technique_common>
    </bind_material>
</instance_geometry>

Is that the recommended way for animating material parameters ?

How does it work when the parameter is an <array> and one wants to animate a single value in the array ?
Can somebody give me an example ?

Because one is a name and one is a reference (path) to a name.

No, not like that. Don’t think of semantic as “targeting” a value literally in the XML content, so much as making a symbolic binding. The semantic is something the effect run-time understands as a symbol identifying linkage to a parameter (scalar or vector or whatever). The <param> element is there to expose that parameter as an interface in the XML description.

Well <param> refers to things semantically so yes your observation is partly true. The run-time has to understand and resolve the linkage to the semantic reference. It’s not (always) literal in the XML sense.

Yes you can use the two elements to create a more explicit description (scaffolding) of the effect parameters you want to animate without ambiguity.

The <bind target=“here[3]”> is an sidref_type so you can use selection syntax at that point in the description.

[quote=“marcus”]

The <bind target=“here[3]”> is an sidref_type so you can use selection syntax at that point in the description.[/quote]

Sorry my question was ambiguous. What i was asking is : when an effect parameter is an array, how do we say in <bind> that we only want to animate a single value in the array ?

For instance :


<effect>
    <newparam sid="numbers">
        <array length="3">
            <float>1.0</float>
            <float>2.0</float>
            <float>3.0</float>
        </array>
    </newparam>
</effect>

...

<node id="transform">
    <translate sid="translate">10 20 30</translate>
</node>

...

<instance_material>
    <bind semantic="numbers" target="transform/translate.X"/>
</instance_material>

In this example, we don’t know where to copy the float value coming from translate.X.
should it go to numbers[0], numbers[1], numbers[2] ?

I guess we are not supposed to only animate a single value. Only the full array can be animated. Is that correct ?

can u please give me the collada file which contains animating material data.I hope this will help a lot for better understanding for material animation
pls…

Is there anyone can provide me the file which contains material animation as discussed in the above list of threads.