Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by doug__ · Jul 12, 2015 at 08:04 AM · shadershaderssurface shader

Why doesn't a material shader render on procedural meshes?

I have a simple class to generate a series of quads facing the camera to test volumetric rendering shaders (see (1)).

With a normal pixel shader, this works fine.

However, with a surface shader, it doesn't seem to work at all; it only seems to find the pixels from existing geometry in the scene, not from the procedurally created meshes.

I've had a good read of the #pragma directives in http://docs.unity3d.com/Manual/SL-SurfaceShaders.html, but I have no idea what I'm doing wrong here.

Anyone know what might be causing this?

It seems specifically to be related to the alpha somehow; removing the alpha pragma makes the slices render correctly, but obviously, without the alpha to make them transparent.

Here's what the normal shader (see below (2)) renders:

alt text

And here's what the surface shader (see below(3)) renders (notice that it render correctly in the scene view, just not the camera view):

alt text

Here are the two shaders, (2) and (3):

 Shader "Shaders/Volume/SphereVolume" {
   Properties {
     _center ("Center", Vector) = (0, 0, 0, 0)
     _size ("Size", Float) = 0
   }
   SubShader {
         Tags {"Queue"="Transparent"}
         Blend SrcAlpha OneMinusSrcAlpha
         Pass {
       CGPROGRAM
       #pragma vertex vert
       #pragma fragment frag
       #pragma target 3.0
 
       #include "UnityCG.cginc"
 
       uniform float3 _center;
       uniform float _size;
 
       struct vertexInput {
         float4 world : POSITION;
         float4 vertex : POSITION;
         float4 uv : TEXCOORD0;
       };
 
       struct fragmentInput{
         float4 position : SV_POSITION;
         float4 world : TEXCOORD1;
       };
 
       fragmentInput vert(vertexInput i){
         fragmentInput o;
         o.position = mul(UNITY_MATRIX_MVP, i.vertex);
         o.world = mul(_Object2World, i.vertex);
         return o;
       }
 
       float4 frag(fragmentInput i) : COLOR {
 
         // Calculate the relative distance from the center point
         float x = (i.world[0] - _center[0]) * (i.world[0] - _center[0]);
         float y = (i.world[1] - _center[1]) * (i.world[1] - _center[1]);
         float z = (i.world[2] - _center[2]) * (i.world[2] - _center[1]);
         float delta = sqrt(x + y + z);
         float inner = 0f;
         if (delta < _size) {
           inner = 1f - delta / _size;
         }
         return float4(1f, 0f, 0f, inner);
       }
       ENDCG
     }
   }
 }
 

and:

 Shader "Shaders/Volume/SphereVolumeMaterial" {
   Properties {
     _center ("Center", Vector) = (0, 0, 0, 0)
     _size ("Size", Float) = 0
   }
   SubShader {
     Cull Off
     CGPROGRAM
 
     #pragma surface surf Lambert alpha keepalpha
 
     uniform float3 _center;
     uniform float _size;
 
     struct Input {
         float3 worldPos;
     };
 
     // Distance between two points
     float distance(float3 a, float3 b) {
       float x = (a[0] - b[0]) * (a[0] - b[0]);
       float y = (a[1] - b[1]) * (a[1] - b[1]);
       float z = (a[2] - b[2]) * (a[2] - b[2]);
       return sqrt(x + y + z);
     }
 
     // See if a value is bounded inside 'magic volume'
     // In this case; a sphere.
     bool bounded(float3 a) {
       return distance(a, _center) < _size;
     }
 
     // Calculate the relative distance from the center point
     void surf (Input IN, inout SurfaceOutput o) {
         if (bounded(IN.worldPos)) {
           float partial = (_size - distance(IN.worldPos, _center)) / _size;
           o.Albedo = fixed3(partial, partial, partial);
         }
     }
 
     ENDCG
   }
   Fallback "Diffuse"
 }
 

and finally, here's the code generating the mesh, which seems fine, but hey, maybe there's something weird up with it... (1):

 using System;
 using System.Collections.Generic;
 using UnityEngine;
 
 namespace Shaders.Volume {
 
   /// Generate a series of parallel planes relative to the camera
   [RequireComponent(typeof(MeshFilter))]
   [RequireComponent(typeof(MeshRenderer))]
   public class SimpleVolumeRenderer : MonoBehaviour {
 
     [Tooltip("The camera to make this volume viewable from")]
     public new UnityEngine.Camera camera;
 
     [Tooltip("The size of the frame to generate for this object")]
     public float size = 1f;
 
     [Tooltip("The number of slices to mesh")]
     public int slices = 10;
     private int slices_;
 
     [Tooltip("The slice interval")]
     public float sliceGap = 0.1f;
 
     /// Internal vertex buffer
     private Vector3[] points;
 
     public void Start() {
       Build();
     }
 
     public void Update() {
       if (slices_ != slices) {
         Build();
       }
       Rebuild();
     }
 
     /// Generate a quad facing the camera at the given offset
     private void BuildQuad(Vector3 origin, Vector3 up, Vector3 right, int offset) {
       points[offset * 4 + 0] = origin + right - up;
       points[offset * 4 + 1] = origin + right + up;
       points[offset * 4 + 2] = origin - right + up;
       points[offset * 4 + 3] = origin - right - up;
     }
 
     /// Generate new points for each quad
     public Vector3[] MeshPoints() {
       if ((points == null) || (points.Length != 4 * slices)) {
         points = new Vector3[4 * slices];
       }
       var offset = size / 2f;
       var origin = gameObject.transform.position;
       var normal = (-1f * camera.transform.forward).normalized;
       var up = camera.transform.up.normalized * offset;
       var right = Vector3.Cross(normal, up).normalized * offset;
       for (var i = 0; i < slices; ++i) {
         var o = i - slices / 2;
         var src = origin - sliceGap * o * normal;
         BuildQuad(src, up, right, i);
       }
       return points;
     }
 
     /// Rebuild vertex points only
     public void Rebuild() {
       MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>();
       meshFilter.mesh.vertices = MeshPoints();
     }
 
     /// Build all details of the mesh
     public void Build() {
       if (camera == null) {
         return;
       }
 
       MeshFilter meshFilter = gameObject.GetComponent<MeshFilter>();
 
       // Generate a set of meshes
       var mesh = new Mesh();
       mesh.Clear();
 
       var verts = MeshPoints();
       mesh.vertices = verts;
 
       // Full quads for the shader to use
       var uvs = new Vector2[4 * slices];
       for (var i = 0; i < slices; ++i) {
         uvs[i * 4 + 0]  = new Vector2(0f, 0f);
         uvs[i * 4 + 1]  = new Vector2(1f, 0f);
         uvs[i * 4 + 2]  = new Vector2(1f, 1f);
         uvs[i * 4 + 3]  = new Vector2(0f, 1f);
       }
       mesh.uv = uvs;
 
       // Always aim at camera
       var normal = (-1f * camera.transform.forward).normalized;
       var normals = new Vector3[4 * slices];
       for (var i = 0; i < slices; ++i) {
         normals[i * 4 + 0] = normal;
         normals[i * 4 + 1] = normal;
         normals[i * 4 + 2] = normal;
         normals[i * 4 + 3] = normal;
       }
       //mesh.normals = normals;
 
       // A series of quads
       var triangles = new int[6 * slices];
       for (var i = 0; i < slices; ++i) {
         triangles[i * 6 + 0] = i * 4 + 2;
         triangles[i * 6 + 1] = i * 4 + 1;
         triangles[i * 6 + 2] = i * 4 + 0;
         triangles[i * 6 + 3] = i * 4 + 0;
         triangles[i * 6 + 4] = i * 4 + 3;
         triangles[i * 6 + 5] = i * 4 + 2;
       }
       mesh.triangles = triangles;
 
       mesh.RecalculateBounds();
       mesh.RecalculateNormals();
       mesh.Optimize();
       meshFilter.mesh = mesh;
       slices_ = slices;
     }
   }
 }
 

out.png (179.6 kB)
out2.png (180.1 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by doug__ · Jul 18, 2015 at 12:43 PM

The solution to this is too add a tag to mark the queue:

 Shader "Shaders/Volume/SphereVolumeMaterial" {
   Properties {
     _center ("Center", Vector) = (0, 0, 0, 0)
     _size ("Size", Float) = 0
   }
   SubShader {
     Tags { "Queue" = "Transparent" } <-- Without this tag, it doesn't work.
     CGPROGRAM
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Referencing the current pixel's world coordinates in the SURF block of a shader 1 Answer

Shadow artifacts on vertex animation shader 1 Answer

viewDir changes with o.Normal 1 Answer

Spherical Hamonics - ShadeSH9 and Surface Shader issue 0 Answers

Problem with Normal Maps 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges