Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to make shader rotate?

Discussion in 'Shaders' started by SamKennedy, Jul 21, 2022.

  1. SamKennedy

    SamKennedy

    Joined:
    Apr 25, 2021
    Posts:
    12
    I have followed this tutorial to make a volumetric shader using ray marching:


    I am happy with the results so far, however I want to be able to rotate the parent object, however if I rotate the cube the shader is applied to, the perspective doesn't change. I've read in the comments that I need to change from sampling world space to object space, however when I update the graph I don't get the desired effect.

    Here is a screenshot of the graph:
    upload_2022-7-21_20-50-34.png

    And here is the code for the Raymarch node:
    Code (CSharp):
    1. void Raymarch_float(float3 rayOrigin, float3 rayDirection, float numSteps, float stepSize, float densityScale, UnityTexture3D Volume, float3 Offset, float numLightSteps, float lightStepSize, float3 lightDir, float lightAbsorb, float darknessThreshold, float transmittance, out float3 Out) {
    2. float density = 0;
    3. float transmission = 0;
    4. float lightAccumulation = 0;
    5. float finalLight = 0;
    6.  
    7. for (int i = 0; i < numSteps; i++) {
    8.     rayOrigin += (rayDirection * stepSize);
    9.  
    10.     float3 samplingPos = rayOrigin + Offset;
    11.  
    12.     float sampledDensity = tex3D(Volume, samplingPos).r;
    13.     density += sampledDensity * densityScale;
    14.    
    15.     float3 lightRayOrigin = samplingPos;
    16.    
    17.     UNITY_LOOP
    18.     for (int j = 0; j < numLightSteps; j++) {
    19.         lightRayOrigin += lightDir * lightStepSize;
    20.         float lightDensity = tex3D(Volume, lightRayOrigin).r;
    21.         lightAccumulation += lightDensity * densityScale;
    22.        
    23.         float3 shadowboxtest = floor( 0.5 + ( abs( 0.5 - lightRayOrigin ) ) );
    24.         float exitshadowbox = shadowboxtest.x + shadowboxtest.y + shadowboxtest.z;
    25.  
    26.         if(lightAccumulation > 100 || exitshadowbox >= 1) break;
    27.     }
    28.    
    29.     float lightTransmission = exp(-lightAccumulation);
    30.     float shadow = darknessThreshold + lightTransmission * (1.0 - darknessThreshold);
    31.     finalLight += density * transmittance * shadow;
    32.     transmittance *= exp(-density * lightAbsorb);
    33.    
    34. }
    35.  
    36. transmission = exp(-density);
    37.  
    38. Out = float3(finalLight, transmission, transmittance);
    39. }
    What is the best way to edit the graph and/or code so that when I rotate the cube the shader is assigned to, the "cloud" appears to rotate also?

    Thank you
     
  2. victor_apihtin

    victor_apihtin

    Unity Technologies

    Joined:
    Mar 2, 2021
    Posts:
    28
    It's because your cube rotation is not used really. You are constructing a vector from your camera to a pixel on the cube, and that vector doesn't change no matter how you rotate the cube.
    You could, for example, take that rayDirection before it goes into the node and apply the cube's rotation on it.

    In shader graph it seems you need to use the Transform node, take the rayDirection and transform it into world space. The result of that would be AS IF you rotate the camera around the cube. But remember to normalize your direction vectors, otherwise your rotation is going to be little unintuitive.

    In code you would be using mul(unity_ObjectToWorld, vector) to do perform such operation. For example you could transform samplingPos with it before sampling the volume texture.
     
    Last edited: Jul 22, 2022